Podstawy testowania aplikacji na Androida

Na tej stronie omawiamy podstawowe zasady testowania aplikacji na Androida, w tym sprawdzone metody i zalety tych rozwiązań.

Zalety testowania

Testowanie jest nieodłączną częścią procesu tworzenia aplikacji. Przeprowadzając testy regularnie, możesz sprawdzić jej poprawność, działanie działania aplikacji i łatwości obsługi, jeszcze zanim ją opublikujesz.

Możesz ręcznie przetestować aplikację, korzystając z nawigacji. Możesz użyć różnych urządzeń i emulatorów, zmienić język systemu i spróbować wygenerować z każdym błędem użytkownika lub poznają każdy wzorzec użytkownika.

Testy ręczne są jednak słabo skalowane i można je łatwo przeoczyć. na wystąpienie regresji w działaniu aplikacji. Testy automatyczne wymagają korzystania z narzędzi które przeprowadzają za Ciebie testy, co jest szybsze, bardziej powtarzalne i ogólnie daje bardziej praktyczne opinie na temat aplikacji na wcześniejszym etapie jej tworzenia. proces tworzenia konta.

Rodzaje testów na Androidzie

Aplikacje mobilne są złożone i muszą dobrze działać w wielu środowiskach. Jako dlatego jest wiele rodzajów testów.

Temat

Istnieją na przykład różne typy testów w zależności od tematu:

  • Testowanie funkcjonalne: czy moja aplikacja działa zgodnie z oczekiwaniami?
  • Testy wydajności: czy przeprowadza się szybko i skutecznie?
  • Testowanie ułatwień dostępu: czy dobrze współpracuje z usługami ułatwień dostępu?
  • Testowanie zgodności: czy działa dobrze na każdym urządzeniu i na każdym poziomie interfejsu API?

Zakres

Testy różnią się też w zależności od rozmiaru lub stopnia izolacji:

  • Testy jednostkowe i małe testy sprawdzają tylko bardzo małą część aplikacji, takich jak metoda lub klasa.
  • Kompleksowe testy lub duże testy weryfikują większe części aplikacji na jednocześnie, np. na całym ekranie lub w ramach wzorca przeglądania.
  • Pomiędzy testami znajdują się średnie testy i sprawdzają integrację 2 lub 2 więcej jednostek.
.
Testy mogą być małe, średnie lub duże.
Ilustracja 1. Zakresy testowe w typowej aplikacji.

Istnieje wiele sposobów klasyfikowania testów. Najważniejszą jednak rozróżnieniem dla deweloperów aplikacji to właśnie miejsce, w którym przeprowadza się testy.

Testy instrumentowane a testy lokalne

Testy możesz przeprowadzić na urządzeniu z Androidem lub na innym komputerze:

  • Testy instrumentowane są przeprowadzane na urządzeniach z Androidem – fizycznych lub emulowanych. Aplikacja jest skompilowana i instalowana wraz z aplikacją testową, która wstrzykiwa polecenia i odczytuje stan. Testy instrumentowane to zwykle testy UI, uruchamianie aplikacji i i wchodzić z nim w interakcję.
  • Testy lokalne są przeprowadzane na maszynie do programowania lub na serwerze, więc są też nazywane testami po stronie hosta. Zazwyczaj są małe i szybkie, odizolowane testowany obiekt w pozostałych częściach aplikacji.
.
Testy mogą być przeprowadzane jako testy zinstruowane na urządzeniu lub testy lokalne na komputerze, na którym pracujesz.
Rys. 2: Różne typy testów w zależności od miejsca ich prowadzenia.

Nie wszystkie testy jednostkowe są lokalne, a nie wszystkie kompleksowe testy są przeprowadzane na urządzeniu. Dla: przykład:

  • Wielki test lokalny: możesz użyć symulatora Androida, który działa lokalnie, jak Robolectric.
  • Mały test instrumentalny: aby sprawdzić, czy Twój kod działa dobrze z funkcji platformy, takiej jak baza danych SQLite. Możesz przeprowadzić ten test na na wielu urządzeniach, aby sprawdzić integrację z różnymi wersjami SQLite.

Przykłady

Poniższe fragmenty kodu pokazują, jak korzystać z interfejsu w instrumentowany test UI, który klika element i sprawdza, czy inny .

Espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

Interfejs tworzenia wiadomości

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

Ten fragment kodu zawiera część testu jednostkowego modelu ViewModel (lokalny, po stronie hosta) test):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

Definiowanie strategii testowania

W idealnym świecie należałoby przetestować wszystkie wiersze kodu w aplikacji na każdym urządzeniu. z którymi Twoja aplikacja jest zgodna. To podejście działa zbyt wolno i jest kosztowny.

Dobra strategia testowania pozwala zachować odpowiednią równowagę między rzetelnością ich szybkością i niezawodnością. podobieństwo środowiska testowego do środowiska testowego; o prawidłowości testu decyduje prawdziwe urządzenie. Przeprowadzane są testy o wyższej wierności z emulowanych urządzeń lub z samego urządzenia fizycznego. Mogą być przeprowadzane testy o niższej wierności na JVM lokalnej stacji roboczej. Testy wysokiej dokładności są często wolniejsze, wymagają więcej zasobów, więc nie każdy test powinien być testem wysokiej jakości.

Niepewne wyniki

Błędy występują nawet w prawidłowo zaprojektowanych i zaimplementowanych uruchomieniach testów. Przykład: jeśli przeprowadzasz test na prawdziwym urządzeniu, automatyczna aktualizacja może rozpocząć się i powoduje niepowodzenie testu. Subtelne warunki wyścigu w kodzie mogą występują tylko w niewielkim odsetku czasu. Testy, które nie zaliczają się w 100% czas jest niestabilny.

Testowa architektura

Architektura aplikacji, którą można przetestować, kod ma strukturę, która pozwala aby łatwo przetestować osobno różne elementy. Testowalne architektury mają inne zalety, takie jak lepsza czytelność, łatwość konserwacji, skalowalność oraz możliwość ponownego wykorzystania.

Architektura, której nie można przetestować, zapewnia:

  • Większe, wolniejsze i bardziej niestabilne testy. Klasy, których nie można przetestować, mogą mieć większe testy integracji lub testy interfejsu.
  • Mniej możliwości testowania różnych scenariuszy. Większe testy trwają wolniej, dlatego testowanie wszystkich możliwych stanów aplikacji może być nierealistyczne.

Więcej informacji o wytycznych dotyczących architektury znajdziesz w przewodniku po aplikacji .

Podejścia do odłączenia

Jeśli uda Ci się wyodrębnić część funkcji, klasy lub modułu z reszty, jest łatwiejsze i skuteczniejsze. Jest to tzw. usuwanie połączeń i jest koncepcją najważniejszą dla architektury testowej.

Popularne techniki usuwania połączeń to między innymi:

  • Podziel aplikację na warstwy, takie jak Prezentacja, Domena i Dane. Dostępne opcje podzielić aplikację na moduły, po jednym na każdą funkcję.
  • Unikaj dodawania logiki do encji, które mają duże zależności, takie jak aktywności i fragmentów. Wykorzystaj te zajęcia jako wstęp do platformy przenieść UI i logikę biznesową w inne miejsce, np. do modelu Composable, ViewModel do warstwy domeny.
  • W klasach zawierających logikę biznesową unikaj bezpośrednich zależności od struktury. Na przykład nie używaj kontekstów Androida w modelach ViewModels.
  • Ułatw zastępowanie zależności. Na przykład użyj wartości interfejsy, a nie konkretne implementacje. Używaj Wstrzykiwanie zależności nawet wtedy, gdy nie korzystasz z platformy DI.

Dalsze kroki

Skoro już wiesz, dlaczego warto przeprowadzać testy i jakie są 2 główne typy testów, możesz przeczytaj artykuł Co testować.

Jeśli chcesz utworzyć pierwszy test i uczyć się, w ćwiczeniach z programowania poświęconych testowaniu.