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.
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:
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:
- 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.
- Przykład: test zrzutu ekranu w przypadku przycisku niestandardowego
- 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.
- Przykład: testy zachowania UI, które weryfikują zarządzanie stanem na ekranie
- 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.
- Przykład: najważniejsze ścieżki użytkownika, testy wydajności
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 |
Debugowanie |
Przed scaleniem |
Funkcja |
Poziom funkcji Integracja z komponentami należącymi do innych zespołów |
Imitacje |
Lokalnie |
Możliwe do debugowania |
Przed scaleniem |
Aplikacja |
Poziom aplikacji Integracja z funkcjami lub usługami należącymi do innych zespołów |
Mocked |
Emulator |
Możliwe do debugowania |
Przed scaleniem |
Release Candidate |
Poziom aplikacji integracja z funkcjami lub usługami należącymi do innych zespołów; |
Serwer produkcyjny |
Emulator |
Kompilacja wersji zminifikowanej |
Po połączeniu |
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 |
|
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 |
|
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 |
|
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 jednostek i komponentó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.