Definicja
Testowanie
jest procesem wykonania programu z zamiarem znalezienia błędów w oprogramowaniu, a także walidacją
i weryfikacją
aplikacji pod kątem spełnienie wymagań biznesowych i technicznych. Walidacja odpowiada na pytanie "czy tworzony produkt jest prawidłowy?"
czyli czy spełnia wymagania klienta, natomiast weryfikacja "czy produkt tworzony jest prawidłowo?"
zgodnie ze standardami, wytycznymi i dobrymi praktykami. Testowanie nie jest więc tylko procesem debugowania, wykonywania testów automatycznych i manualnych lecz znacznie szerszym pojęciem, który sprawdza także spełnienie założeń biznesowych, oczekiwań klienta, wydajności sprzętowej, poprawności kodu czy też użyteczności w kontekście User Experience
. Testowanie dostarcza informacji o jakości testowanego produktu i jest jednym z procesów zapewnienia jego jakości, który nierzadko składa się z kolejnych faz testów: jednostkowych, integracyjnych, systemowych i akceptacyjnych.
Błąd i usterka
W kontekście terminu testowania warto wyróżnić pojęcię błędu, usterki i awarii. Błąd
jest działaniem człowieka powodującym powstanie nieprawidłowego wyniku, usterka
skutkiem błędu programisty natomiast awaria
odchyleniem od spodziewanego zachowania czy wyniku. Usterka może lecz nie musi powodować awarii. W procesie tworzenia i rozwijania aplikacji nie sposób ustrzec się wszystkich błędów, które mogą się ujawnić dopiero w szczególnych przypadkach. Należy zatem zdać sobie sprawę z ludzkiej omylności. Testowanie pomaga ujawnić usterki, jednakże gruntowne przeprowadzenie jest najczęściej niewykonalne. Wczesne i regularne testowanie ułatwia wykrywanie usterek, pomaga utrzymać oprogramowanie w dobrej jakości i zapobiega kumulowaniu się błędów.
Testy jednostkowe
Testy jednostkowe
(unit test
) polegają na wyodrębnieniu składowych elementów kodu takich jak: metody
, klasy
czy moduły
i poddaniu weryfikacji ich sposobu działania niezależnie od reszty aplikacji. Aby testy miały sens i nie były zafałszowane należy wyeliminować wpływ innych elementów systemu na testowaną jednostkę. Należą one do testów automatycznych
, a za ich tworzenie powinien odpowiadać programista. Dzięki czemu już na wczesnym etapie tworzenia oprogramowania możliwe jest wykrycie usterki. Do przeprowadzania testów jednostkowych można wykorzystać np. bibliotekę jUnit
wraz z Mockito
do tworzenia zaślepek
. Testy jednostkowe mogą być lokalne
- przeprowadzane na maszynie wirtualnej oraz instrumentalne
- wykonywane na urządzeniu lub emulatorze.
Testy integracyjne
W celu wykrycia błędów w interfejsach oraz interakcjach pomiędzy integrowanymi elementami systemu należy przeprowadzić testy integracyjne
. Polegają one przede wszystkim na testowaniu wymiany danych między testowanymi elementami oraz sprawdzaniu reakcji na wywoływane zdarzenia. Mogą być one wykonywane na wielu poziomach oraz odnosić się do elementów różnej wielkości jak np.: integracja funkcjonalności systemu, integracja modułów czy systemów. Zatem dodanie nowej funkcjonalności, użycie zewnętrznej biblioteki czy wymiana danych z serwerem są dobrym powodem do przeprowadzenia testów. Narzędziami do przeprowadzania testów integracyjnych na Android mogą być m.in. automatyczne testy UI
wykorzystając np. bibliotekę Espresso
czy testy manualne prowadzone przez człowieka. Testy integracyjne należą do testów, które mogą leżeć w kompetencji programisty.
Testy systemowe
Testy systemowe
dotyczą w pełni zintegrowanego systemu i sprawdzają czy spełnia on założenia specyfikacji. Weryfikują system pod względem realizacji wymagań klienta w środowisku jak najbardziej zbliżonym do produkcyjnego. Testy systemowe mogą być oparte o wymagania lub proces biznesowy oraz dotyczyć wydajności (np. narzędzia diagnostyczne w Android Studio
czy Firebase Performance Monitoring
), użyteczności, bezpieczeństwa i przenaszalności (gdzie te ostatnie nie dotyczą platformy Android). W kontekście testowanych obszarów oraz wymagań technicznych klienta należy w odpowiedni sposób dobrać zestaw urządzeń testowych lub wykorzystać farmę testową
. Przygotowanie i przeprowadzanie testów oraz podsumowanie wyników spoczywa na zespole testującym.
Testy akceptacyjne
Celem testów akceptacyjnych jest uzyskanie formalnego potwierdzenia wykonania aplikacji o ustalonej jakości zgodnie z ustalonymi założeniami i wymaganiami wg specyfikacji. Testy przeprowadzane są przez zespół odbiorców i twórców na środowisku produkcyjnym lub najbardziej zbliżonym do środowiska docelowego. Można wyróżnić etap testów alfa
dokonywany przez wewnętrzny zespół testowy niezależny od zespołu twórców oraz testy beta
wykonywane na zewnątrz firmy w różnorodnych środowiskach testowych. W przypadku tworzenia aplikacji przeznaczonych na sklep Google Play
wydanie aplikacji w wersji beta przeznaczonej dla użytkowników zapisanych na betatesty
może być sposobem realizacji testów akceptacyjnych. Wykorzystanie narzędzi automatycznie rejestrujących awarie aplikacji z urządzeń użytkowników np. Firebase Crashlytics
pozwala poznać błędy i lokalizować usterki co ułatwia naprawę popełnionych błędów.
Wyzwania
Podstawowymi czynnościami procesu testowania aplikacji na platformę Android, które spoczywają na barkach programisty jest debugowanie
oraz pisanie testów automatycznych
. Niestety w odróżnieniu od innych środowisk przeprowadzenie testów jednostkowych w Android jest utrudnione ze względu na SDK i zależności sprzętowe. Wykorzystywane w środowisku deweloperskim klasy pochodzące z Android SDK
we fragmentach kodu aplikacji są na dobrą sprawę zaślepką bez implementacji zachowania, które dopiero uruchomione na fizycznym urządzeniu czy emulatorze zyskują pełnie działania. Testy jednostkowe mogą być bez przeszkód wykonane na kodzie wolnym od zależności klas Android SDK co tyczy się przede wszystkim klas typu Utils i logiki. Co więcej testowaniu powinny podlegać komponenty Androida, których cykl życia jest tworzony i zarządzany przez system. Przeprowadzenie testów na klasach z Android SDK, a przede wszystkim komponentów rodzi problem braku instancji co nawet w przypadku stworzenia zaślepek za pomocą zewnętrznych bibliotek nie jest trywialne. Rozwiązaniem tego problemu może być wykorzystanie dedykowanych bibliotek np. Robolectric
, które dostarczają środowiska uruchomieniowego dla testów jednostkowych. Ze względu na fragmentację platformy oraz dokonywane zmiany w SDK należy mieć na uwadze również to, że aplikacja może w różny sposób zachowywać się na różnych telefonach. Warto zatem przeprowadzać także automatyczne testy UI oraz testy manualne właściwie dobierając przekrój zestawu urządzeń testowych.