Proces testowy

Testowanie

  |   5 min czytania

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.