Strategie testowania

Automatyczne testowanie pomaga na wiele sposobów poprawić jakość aplikacji. Na przykład pomaga w przeprowadzaniu weryfikacji, wykrywaniu regresji i sprawdzaniu zgodności. Dobra strategia testowania pozwala korzystać z automatycznych testów, 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 na bieżąco otrzymywać informacje o tym, jak działa kod. Dobra strategia testowania:

  • Wykrywa problemy jak najwcześniej.
  • Szybkie wykonywanie.
  • Wyraźnie wskazuje, kiedy coś wymaga poprawy.

Na tej stronie dowiesz się, jakie rodzaje testów warto przeprowadzać, gdzie i jak często.

Piramida testów

Testy w nowoczesnych aplikacjach możesz kategoryzować według rozmiaru. Małe testy 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 w utrzymaniu. Duże testy są jednak bardziej precyzyjne* i mogą wykryć znacznie więcej problemów naraz.

*Wierność odnosi się do podobieństwa środowiska wykonawczego testu do środowiska produkcyjnego.

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

Większość aplikacji powinna mieć wiele małych testów i stosunkowo niewiele dużych. Rozkład testów w każdej kategorii powinien tworzyć piramidę, w której podstawę stanowią liczne małe testy, a wierzchołek – mniej liczne duże testy.

Minimalizowanie kosztów błędu

Dobra strategia testowania maksymalizuje produktywność programistów, a jednocześnie minimalizuje koszty znajdowania błędów.

Rozważmy przykład strategii, która może być nieefektywna. W tym przypadku liczba testów według rozmiaru nie tworzy piramidy. Jest zbyt wiele dużych testów kompleksowych i zbyt mało testów interfejsu komponentów:

Strategia z przewagą testów ręcznych, w której testy urządzeń są wykonywane tylko w nocy.
Rysunek 2. Strategia z przewagą testów ręcznych, w której testy urządzeń są wykonywane tylko w nocy.

Oznacza to, że przed scaleniem przeprowadzono zbyt mało testów. Jeśli wystąpi błąd, testy mogą go nie wykryć do czasu uruchomienia nocnych lub tygodniowych testów kompleksowych.

Warto zastanowić się, jakie ma to znaczenie dla kosztów identyfikowania i usuwania błędów oraz dlaczego warto skupiać się w testach na mniejszych i częstszych testach:

  • Jeśli błąd zostanie wykryty przez test jednostkowy, zwykle jest naprawiany w ciągu kilku minut, więc koszt jest niski.
  • Test kompleksowy może wykryć ten sam błąd dopiero po kilku dniach. Może to zaangażować wielu członków zespołu, co zmniejszy ogólną produktywność i może opóźnić wprowadzenie produktu na rynek. Koszt tego błędu jest wyższy.

Niemniej jednak nieefektywna strategia testowania jest lepsza niż brak jakiejkolwiek strategii. Gdy błąd trafi do środowiska produkcyjnego, jego naprawienie na urządzeniach użytkowników zajmuje dużo czasu, czasem nawet tygodnie, więc pętla opinii jest najdłuższa i najdroższa.

skalowalną strategię testowania,

Piramida testów jest tradycyjnie podzielona na 3 kategorie:

  • Testy jednostkowe
  • Testy integracji
  • testy kompleksowe,

Jednak te pojęcia nie mają precyzyjnych definicji, więc zespoły mogą chcieć inaczej zdefiniować swoje kategorie, np. używając 5 warstw:

5-warstwowa piramida testów z kategoriami testów jednostkowych, testów komponentów, testów funkcji, testów aplikacji i testów wersji kandydującej w kolejności rosnącej.
Rysunek 3. 5-warstwowa piramida testów.
  • Test jednostkowy jest przeprowadzany na komputerze hosta i weryfikuje pojedynczą jednostkę logiczną bez zależności od platformy Android.
    • Przykład: weryfikowanie błędów o 1 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 komponentu obejmuje wyższe poziomy abstrakcji niż poszczególne metody i klasy.
  • Test funkcji weryfikuje interakcję co najmniej 2 niezależnych komponentów lub modułów. Testy funkcji są większe i bardziej złożone, a zwykle działają na poziomie funkcji.
  • Test aplikacji weryfikuje funkcjonalność całej aplikacji w postaci pliku binarnego, który można wdrożyć. Są to duże testy integracji, które jako testowany system wykorzystują binarny plik z możliwością debugowania, np. wersję deweloperską, która może zawierać punkty zaczepienia testów.
    • Przykład: test zachowania interfejsu w celu sprawdzenia zmian konfiguracji na urządzeniu składanym, testy lokalizacji i ułatwień dostępu
  • Test wersji kandydującej sprawdza działanie wersji gotowej do wdrożenia. Są one podobne do testów aplikacji, z tą różnicą, że binarna wersja aplikacji jest zminimalizowana i zoptymalizowana. Są to duże testy integracyjne typu end-to-end, które są przeprowadzane w środowisku jak najbardziej zbliżonym do produkcyjnego, ale bez udostępniania aplikacji publicznym kontom użytkowników ani publicznym backendom.

Podział ten uwzględnia wierność, czas, zakres i poziom izolacji. Możesz przeprowadzać różne rodzaje testów na wielu warstwach. 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 minimalną liczbą zależności.

Nie

Lokalny

Debugowanie

Przed scaleniem

Komponent

Poziom modułu lub komponentu

Wiele zajęć naraz

Nie

Lokalne
Robolectric
Emulator

Debugowanie

Przed scaleniem

Funkcja

Poziom funkcji

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

Mocked

Lokalne
Robolectric
Emulator
Urządzenia

Debugowanie

Przed scaleniem

Aplikacja

Poziom aplikacji

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

Mocked
Serwer testowy
Serwer produkcyjny

Emulator
Urządzenia

Debugowanie

Przed scaleniem
Po scaleniu

Wersja kandydująca do publikacji

Poziom aplikacji

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

Serwer produkcyjny

Emulator
Urządzenia

Zminimalizowana wersja

Po scaleniu
Przed premierą

Określ kategorię testu

Zasadniczo należy brać pod uwagę najniższą warstwę piramidy, która może zapewnić zespołowi odpowiedni poziom informacji zwrotnych.

Weźmy na przykład testowanie wdrożenia tej funkcji: interfejsu procesu logowania. W zależności od tego, co chcesz przetestować, wybierz różne kategorie:

Obiekt testu

Opis tego, co jest testowane

Kategoria testowa

Przykładowy typ testu

Logika sprawdzania poprawności formularza

Klasa, która sprawdza adres e-mail za pomocą wyrażenia regularnego i weryfikuje, czy pole hasła zostało wypełnione. Nie ma żadnych zależności.

Testy jednostkowe

Lokalny test jednostkowy JVM

Działanie interfejsu formularza logowania

Formularz z przyciskiem, który jest włączony tylko wtedy, gdy formularz został zweryfikowany

Testy komponentów

Test zachowania interfejsu przeprowadzany w Robolectric

Wygląd interfejsu formularza logowania

formularz zgodny ze specyfikacją UX;

Testy komponentów

Test zrzutu ekranu podglądu tworzenia

Integracja z menedżerem uwierzytelniania

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

Testy funkcji

Test JVM z użyciem atrap

Okno logowania

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

Testy aplikacji

Test zachowania interfejsu przeprowadzany w Robolectric

Najważniejsza ścieżka użytkownika: logowanie

Pełny proces logowania przy użyciu konta testowego na serwerze przejściowym.

Wersja kandydująca do publikacji

Testowanie działania interfejsu Compose na urządzeniu

W niektórych przypadkach przynależność do danej kategorii może być subiektywna. Istnieją dodatkowe powody, dla których test może zostać przesunięty w górę lub w dół, takie jak koszt infrastruktury, niestabilność i długi czas trwania testu.

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

Testy ręczne mogą być również częścią Twojej strategii testowania. Zazwyczaj zespoły ds. kontroli jakości przeprowadzają testy wersji kandydującej, ale mogą też brać udział w innych etapach. Na przykład testowanie eksploracyjne w celu wykrycia błędów w funkcji bez skryptu.

Infrastruktura testowa

Strategia testowania musi być wspierana przez infrastrukturę i narzędzia, które pomogą deweloperom w ciągłym przeprowadzaniu testów i egzekwowaniu reguł gwarantujących, że wszystkie testy zostaną zaliczone.

Możesz podzielić testy na kategorie według zakresu, aby określić, kiedy i gdzie mają być uruchamiane poszczególne testy. Na przykład zgodnie z modelem 5-warstwowym:

Kategoria

Środowisko (gdzie)

Aktywator (kiedy)

Jednostka

[Lokalne][4]

Każde zatwierdzenie

Komponent

Lokalny

Każde zatwierdzenie

Funkcja

Lokalnie i na emulatorach

Przed scaleniem, przed scaleniem lub przesłaniem zmiany

Aplikacja

Lokalnie, emulatory, 1 telefon, 1 składany

Po scaleniu, po scaleniu lub przesłaniu zmiany

Wersja kandydująca do publikacji

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

Przed premierą

  • Testy jednostkowekomponentów są uruchamiane w systemie ciągłej integracji przy każdej nowej zmianie, ale tylko w przypadku modułów, których dotyczy zmiana.
  • Wszystkie testy jednostkowe, komponentówfunkcji są przeprowadzane przed scaleniem lub przesłaniem zmiany.
  • Testy aplikacji są przeprowadzane po scaleniu.
  • Testy Release Candidate są przeprowadzane codziennie w nocy na telefonie, urządzeniu składanym i tablecie.
  • Przed opublikowaniem wersji przeprowadzane są testy wersji kandydującej na dużej liczbie urządzeń.

Te reguły mogą się zmieniać z czasem, gdy liczba testów wpływa na produktywność. Jeśli na przykład przeniesiesz testy do harmonogramu nocnego, możesz skrócić czas kompilacji CI i testów, ale możesz też wydłużyć pętlę opinii.