Strategie testowania

Automatyczne testowanie pomaga poprawić jakość aplikacji na wiele sposobów. Na przykład pomaga w sprawdzaniu, wykrywaniu regresji i weryfikowaniu zgodności. Dobra strategia testowania umożliwia korzystanie z automatycznego testowania, aby skupić się na ważnej korzyści: wydajności deweloperów.

Zespoły osiągają wyższy poziom produktywności, gdy stosują systematyczne podejście do testowania w połączeniu z ulepszeniami infrastruktury. Dzięki temu możesz otrzymywać na bieżąco informacje o tym, jak działa kod. Dobra strategia testowania:

  • Wyłapuje problemy tak szybko, jak to możliwe.
  • Wykonuje szybko.
  • wyraźnie wskazuje, co należy poprawić;

Na tej stronie możesz zdecydować, jakie testy wdrożyć, gdzie je przeprowadzać i jak często.

Piramida testowania

W nowoczesnych aplikacjach możesz kategoryzować testy według rozmiaru. Testy małe skupiają się tylko na niewielkiej części kodu, dzięki czemu są szybkie i niezawodne. Duże testy mają szeroki zakres i wymagają bardziej złożonych konfiguracji, które są trudne do utrzymania. Jednak duże testy są bardziej dokładne* i mogą wykryć znacznie więcej problemów w jednym kroku.

*Zgodność odnosi się do podobieństwa środowiska testowego do środowiska produkcyjnego.

Rozkład liczby testów według zakresu jest zwykle przedstawiany w postaci piramidy.
Rysunek 1. Rozkład liczby testów według zakresu jest zwykle przedstawiany w postaci piramidy.

Większość aplikacji powinna mieć wiele małych testów i względnie niewiele dużych testów. Rozkład testów w każdej kategorii powinien tworzyć piramidę, w której większa liczba mniejszych testów stanowi podstawę, a mniejsza liczba większych testów stanowi wierzchołek.

Zminimalizuj koszt błędu

Dobra strategia testowania maksymalizuje produktywność deweloperów przy jednoczesnym minimalizowaniu kosztów znajdowania błędów.

Rozważ przykład strategii, która może być nieskuteczna. W tym przypadku liczba testów według rozmiaru nie jest skonstruowana w formie piramidy. Zbyt wiele jest obszernych testów kompleksowych i zbyt mało testów UI komponentów:

Strategia z cięższym wierzchołkiem, w której wiele testów jest wykonywanych ręcznie, a testy urządzeń są wykonywane tylko w nocy.
Rysunek 2. Strategia z cięższym wierzchołkiem, w której wiele testów jest wykonywanych ręcznie, a testy urządzeń są wykonywane tylko w nocy.

Oznacza to, że przed scaleniem trwa za mało testów. W przypadku błędu testy mogą go wychwycić dopiero podczas kompleksowych testów wieczornych lub cotygodniowych.

Warto wziąć pod uwagę konsekwencje, jakie ma to na koszt wykrywania i naprawiania błędów, oraz dlaczego warto skupić się na mniejszych i częstszych testach:

  • Gdy błąd zostanie wykryty przez test jednostkowy, można go zwykle naprawić w kilka minut, więc koszty są niewielkie.
  • Wykrywanie tego samego błędu może zająć kilka dni. Może to zająć czas wielu członków zespołu, co zmniejszy ogólną produktywność i może opóźnić wydanie. Koszt tego błędu jest wyższy.

Jednak nieefektywna strategia testowania jest lepsza niż żadna strategia. Po wprowadzeniu błędu do środowiska produkcyjnego poprawka będzie długo trafiać na urządzenia użytkownika – czasem nawet kilka tygodni, więc pętla informacji zwrotnych jest najdłuższa i najdroższa.

Skalowalna strategia testowania

Piramida testów jest tradycyjnie podzielona na 3 kategorie:

  • Testy jednostkowe
  • Testy integracji
  • Kompleksowe testy.

Te pojęcia nie mają jednak precyzyjnych definicji, więc zespoły mogą definiować kategorie na różne sposoby, np. za pomocą 5 poziomów:

5-warstwowa piramida testowa zawierająca kategorie: testy jednostkowe, składowe, testy funkcji, testy aplikacji i testy kandydujące, w kolejności rosnącej.
Rysunek 3. Piramida testów składająca się z 5 poziomów.
  • Test jednostkowy jest wykonywany na komputerze hosta i sprawdza pojedynczą funkcjonalną jednostkę logiki bez zależności od platformy Android.
    • Przykład: sprawdzanie błędów typu „o jeden” w funkcji matematycznej.
  • Test komponentu sprawdza funkcjonalność lub wygląd modułu lub komponentu niezależnie od innych komponentów w systemie. W przeciwieństwie do testów jednostkowych obszar testu składowego obejmuje wyższe wartości abstrakcyjne, które są większe niż w przypadku poszczególnych metod i klas.
  • Test funkcji sprawdza interakcję co najmniej 2 niezależnych komponentów lub modułów. Testy funkcji są większe i bardziej złożone oraz zazwyczaj działają na poziomie funkcji.
  • Test aplikacji służy do weryfikacji działania całej aplikacji w postaci możliwych do wdrożenia plików binarnych. To duże testy integracji, które używają binarnych plików do debugowania, takich jak wersja deweloperska, która może zawierać elementy testowe, jako system testowany.
    • Przykład: test zachowania interfejsu w celu weryfikacji zmian konfiguracji w testach wersji składanej, lokalizacji i ułatwień dostępu
  • Test wersji kandydującej sprawdza funkcjonalność wersji kandydackiej. Są one podobne do testów aplikacji, z tą różnicą, że binarne pliki aplikacji są skompresowane i zoptymalizowane. To duże testy integracji end-to-end, które są przeprowadzane w środowisku zbliżonym do środowiska produkcyjnego, bez wystawiania aplikacji na publiczne konta użytkowników lub publiczne backendy.

Kategoryzacja uwzględnia wierność, czas, zakres i poziom izolacji. Możesz przeprowadzać różne rodzaje testów na różnych poziomach. Na przykład warstwa testów aplikacji może zawierać testy zachowania, zrzutów ekranu i wydajności.

Zakres

Dostęp do sieci

Realizacja

Typ kompilacji

Cykl życia

Jednostka

pojedyncza metoda lub klasa z minimalnymi zależnościami;

Nie

Lokalny

Możliwe do debugowania

Przed scaleniem

Składnik

Poziom modułu lub komponentu

Wiele zajęć razem

Nie

Lokalnie
Robolectric
Emulator

Debugowanie

Przed scaleniem

Funkcja

Poziom funkcji

Integracja z komponentami należącymi do innych zespołów

Imitacje

Lokalnie
Robolectric
Emulator
Urządzenia

Możliwe do debugowania

Przed scaleniem

Aplikacja

Poziom aplikacji

Integracja z funkcjami lub usługami należącymi do innych zespołów

Mocked
Staging server
Prod server

Emulator
Urządzenia

Możliwe do debugowania

Przed scaleniem
Po scaleniu

Release Candidate

Poziom aplikacji

integracja z funkcjami lub usługami należącymi do innych zespołów;

Serwer produkcyjny

Emulator
Urządzenia

Kompilacja wersji zminifikowanej

Po połączeniu
przed premierą

Wybór kategorii testu

Zasadniczo należy wybrać najniższy poziom piramidy, który może dać zespołowi odpowiedni poziom informacji zwrotnych.

Możesz na przykład przetestować implementację tej funkcji: interfejsu użytkownika podczas logowania. W zależności od tego, co chcesz przetestować, wybierz różne kategorie:

Temat testu

Opis tego, co jest testowane

Kategoria Test

Przykładowy typ testu

Logika walidatora formularzy

Klasa, która sprawdza poprawność adresu e-mail na podstawie wyrażenia regularnego i sprawdza, czy zostało podane hasło. Nie ma żadnych zależności.

Testy jednostkowe

Test lokalnej jednostki JVM

Zachowanie interfejsu formularza logowania

Formularz z przyciskiem, który jest włączony tylko po zweryfikowaniu formularza.

Testy komponentów

Test zachowania interfejsu uruchomiony na urządzeniach Robolectric

Wygląd interfejsu formularza logowania

formularz zgodny ze specyfikacją UX;

Testy komponentów

Testowanie zrzutu ekranu w oknie tworzenia

Integracja z menedżerem uwierzytelniania

Interfejs użytkownika, który wysyła dane logowania do menedżera uwierzytelniania i odbiera odpowiedzi, które mogą zawierać różne błędy.

Testy funkcji

Test JVM z użyciem fałszywych danych

Okno logowania

Ekran z formularzem logowania po naciśnięciu przycisku logowania.

Testy aplikacji

test zachowania interfejsu użytkownika przeprowadzany w Robolectric.

Kluczowa ścieżka użytkownika: logowanie

Pełny proces logowania z użyciem konta testowego na serwerze testowym

Kandydat do wydania

Kompleksowy test zachowania interfejsu Compose przeprowadzany na urządzeniu

W niektórych przypadkach przynależność do danej kategorii może być subiektywna. Test może zostać przesunięty w górę lub w dół z dodatkowych powodów, takich jak koszt infrastruktury, niestabilność i długi czas testowania.

Pamiętaj, że kategoria testu nie określa typu testu, a nie wszystkie funkcje muszą być testowane w każdej kategorii.

Testowanie ręczne może też być częścią strategii testowania. Zwykle zespoły kontroli jakości przeprowadzają testy wersji dla kandydatów, ale mogą też uczestniczyć w innych etapach. Na przykład testowanie eksploracyjne w celu wykrycia błędów w funkcji bez skryptu.

Testowanie infrastruktury

Strategia testowania musi być obsługiwana przez infrastrukturę i narzędzia, które pomagają deweloperom stale uruchamiać testy i egzekwować reguły gwarantujące, że wszystkie testy zostaną zaliczone.

Testy możesz podzielić na kategorie według zakresu, aby określić, kiedy i gdzie mają być uruchamiane. Na przykład w przypadku modelu 5-warstwowego:

Kategoria

Środowisko (gdzie)

Aktywator (kiedy)

Jednostka

[Local][4]

Każde zatwierdzenie

Składnik

Lokalny

Każde zatwierdzenie

Funkcja

Lokalne i emulatory

Przed scaleniem, przed przesłaniem zmiany lub przed przesłaniem zmiany po scaleniu.

Aplikacja

Lokalnie, emulatory, 1 telefon, 1 składane urządzenie

Po scalerowaniu, po scalerowaniu lub po przesłaniu zmiany

Release Candidate

8 różnych telefonów, 1 składany i 1 tablet

Przed premierą

  • Testy jednostekkomponentów są wykonywane w systemie ciągłej integracji dla każdego nowego zatwierdzenia, ale tylko w przypadku modułów, których dotyczy problem.
  • Wszystkie testy jednostek, komponentów i funkcji są wykonywane przed scaleniem lub przesłaniem zmiany.
  • Testy aplikacji są wykonywane po scalejacji.
  • Testy Release Candidate są przeprowadzane co noc na telefonie, urządzeniu składanym i tablecie.
  • Przed opublikowaniem wersja kandydata do wydania jest testowana na wielu urządzeniach.

Te reguły mogą się zmieniać z upływem czasu, gdy liczba testów wpływa na wydajność. Jeśli na przykład przeniesiesz testy na nocny harmonogram, możesz skrócić czas kompilacji i testowania CI, ale możesz też wydłużyć pętlę informacji zwrotnych.