Skip to content

Commit e8781a7

Browse files
committed
unit test post published and orchestrator and recorder added to espresso
1 parent 025dd17 commit e8781a7

File tree

4 files changed

+14
-6
lines changed

4 files changed

+14
-6
lines changed

_drafts/2019-02-04-espresso.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ keywords: "testowanie, testing, testy, jednostkowe, integracyjne, manualne, ui,
1111
---
1212

1313
## Testy UI
14-
`Testy intregracyjne` są przeprowadzane w celu wykrycia błędów zachodzących w interakcji pomiędzy integrowanymi interfejsami systemu i polegają na testowaniu reakcji na wywołane zdarzenia oraz wymianie danych między testowanymi elementami. Wykonywane są na wielu poziomach testowania i dotyczą całego obszaru integracji (funkcjonalności, moduły, systemy). Realizacją testów integracyjnych w Android są `testy UI` (`testy interfejsu użytkownika`) polegające na przeprowadzeniu zestawu ciągu operacji w docelowej aplikacji z punktu widzenia użytkownika. `Ręczne testy` przeprowadzane przez testera choć ważne są jednak obciążone sporym nakładem czasowym i podatne na błędy, dlatego warto dążyć do automatyzacji testów UI. Instrumentalne `automatyczne testy` interfejsu użytkownika mogą dotyczyć jednej aplikacji lub interakcji między aplikacjami czy też aplikacją i systemem. Przykładem biblioteki przeznaczonej do testów UI obejmujących jedną aplikację jest `Espresso`, a dla interakcji między aplikacjami i systemem np. `UI Automator`.
14+
`Testy intregracyjne` są przeprowadzane w celu wykrycia błędów zachodzących w interakcji pomiędzy integrowanymi interfejsami systemu i polegają na testowaniu reakcji na wywołane zdarzenia oraz wymianie danych między testowanymi elementami. Wykonywane są na wielu poziomach testowania i dotyczą całego obszaru integracji (funkcjonalności, moduły, systemy). Realizacją testów integracyjnych w Android są `testy UI` (`testy interfejsu użytkownika`) polegające na przeprowadzeniu zestawu ciągu operacji w docelowej aplikacji z punktu widzenia użytkownika. `Ręczne testy` przeprowadzane przez testera choć ważne są jednak obciążone sporym nakładem czasowym i podatne na błędy, dlatego warto dążyć do automatyzacji testów UI. Instrumentalne `automatyczne testy` interfejsu użytkownika mogą dotyczyć jednej aplikacji lub interakcji między aplikacjami czy też aplikacją i systemem. Przykładem biblioteki przeznaczonej do testów UI obejmujących jedną aplikację jest `Espresso`, a dla interakcji między aplikacjami i systemem np. `UI Automator`. Jako alternatywę można rozważyć biblioteki `Robotium` lub `Appium`.
1515

1616
## Charakterystyka
17-
Testy jednej aplikacji weryfikują zachowanie docelowej aplikacji w stosunku do przeprowadzonych ustalonych działań lub wprowadzenia danych w ekranie aplikacji (`Aktywności`) przez użytkownika. Espresso w sposób automatyczny umożliwia przeprowadzanie symulacji akcji użytkownika w aplikacji oraz sprawdzenie oczekiwanego rezultatu po stronie UI co może przełożyć się na zwiększenie jakości `User Experience`. Udostępnione podstawowe API jest niewielkie, proste, intuicyjne i działa w oparciu o interakcję oraz asercje stanów widoków. Przeznaczone jest do operowania na konkretnych widokach oraz wybranych elementach kolekcji widoków. Espresso zapewnia właściwe zarządzanie wątkiem głównym dzięki czemu uruchamia polecenia testowe we właściwym czasie co zwalnia programistę z obowiązku tworzenia tymczasowych obejść.
17+
Testy jednej aplikacji weryfikują zachowanie docelowej aplikacji w stosunku do przeprowadzonych ustalonych działań lub wprowadzenia danych w ekranie aplikacji (`Aktywności`) przez użytkownika. Espresso w sposób automatyczny umożliwia przeprowadzanie symulacji akcji użytkownika w aplikacji oraz sprawdzenie oczekiwanego rezultatu po stronie UI co może przełożyć się na zwiększenie jakości `User Experience`. Udostępnione podstawowe API jest niewielkie, proste, intuicyjne i oparte jest o interakcję oraz asercje stanów widoków. Przeznaczone jest do operowania na konkretnych widokach oraz wybranych elementach kolekcji widoków. Espresso działa szybko i zapewnia właściwe zarządzanie wątkiem głównym dzięki czemu uruchamia polecenia testowe we właściwym czasie co zwalnia programistę z obowiązku tworzenia tymczasowych obejść. Aby uniknąć nieoczekiwanych rezultatów i błędów w przeprowadzanych testach rekomendowane jest wyłączenie (na testowanym urządzeniu fizycznym lub wirtualnym) animacji systemowych dostępnych w opcjach programisty (animacje okien, animacje przejścia, czas animacji).
1818

1919
>**Przykład**
2020
>Na podstawie Aktywności `MainActivity` zostaną przedstawione możliwości implementacji automatycznych testów UI w Espresso.
@@ -92,7 +92,7 @@ class EspressoTest {
9292
{% endhighlight %}
9393

9494
## Dostęp do widoków
95-
Aby znaleźć widok należy wywołać `onView` lub dla kolekcji widoków `onData` oraz przekazać zapytanie (`matcher`) wskazujące na oczekiwany widok np. na podstawie id (`withId`), zawartości (`withText`, `containsString`) czy typu (`instanceOf`). W rezultacie zostanie zwrócony obiekt typu `ViewInteraction` lub `DataInteraction` (dla kolekcji widoków), który umożliwia przeprowadzenie interakcji z widokiem. Należy mieć jednak na uwadze, że Android nie gwarantuje unikatowych ID elementów co w przypadku sytuacji używania tego samego ID przez kilka różnych widoków może powodować problemy (wyrzuci wyjątek `AmbiguousViewMatcherException`). W takich sytuacjach warto wykorzystywać kombinacje dopasowań za pomocą metody `allOf`. W przypadku kolekcji widoków takich jak np. `ListView` nie ma pewności uzyskania żądanego widoku za pomocą `onView` (tylko część elementów jest widoczna) dlatego dostęp powinien odbywać się poprzez dane za pomocą `onData`.
95+
Aby znaleźć widok należy wywołać `onView` lub dla kolekcji widoków `onData` oraz przekazać zapytanie (`matcher`) wskazujące na oczekiwany widok np. na podstawie id (`withId`), zawartości (`withText`, `containsString`) czy typu (`instanceOf`). W rezultacie zostanie zwrócony obiekt typu `ViewInteraction` lub `DataInteraction` (dla kolekcji widoków), który umożliwia przeprowadzenie interakcji z widokiem. Trzeba mieć jednak na uwadze, że Android nie gwarantuje unikatowych ID elementów co w przypadku sytuacji używania tego samego ID przez kilka różnych widoków może powodować problemy (wyrzucenie wyjątku `AmbiguousViewMatcherException`). W takich sytuacjach warto wykorzystywać kombinacje dopasowań za pomocą metody `allOf`. W przypadku kolekcji widoków takich jak np. `ListView` nie ma pewności uzyskania żądanego widoku za pomocą `onView` (tylko część elementów jest widoczna) dlatego dostęp powinien odbywać się poprzez dane za pomocą `onData`. Espresso potrafi również poradzić sobie widokami typu `WebView`.
9696

9797
{% highlight kotlin %}
9898
@RunWith(AndroidJUnit4::class)
@@ -127,7 +127,7 @@ class AccessViewTest {
127127
{% endhighlight %}
128128

129129
## Przeprowadzenie akcji
130-
Uruchomienie akcji następuje poprzez wyołanie metody `perform` klasy `ViewInteraction` lub `DataInteraction` w zależności od rodzaju elementu oraz przekazanie obiektów typu `ViewAction` jako argumentów. Akcje jakie można wykonać to m.in. `click`, `typeText`, `scrollTo`, `pressKey`, `clearText`. Ponadto jeśli podejmowana akcja dotyczy intencji (`Intent`) można wykorzystać zasadę `IntentsTestRule`, która waliduje intencje wysłane przez testowane aplikację oraz metody weryfikujące `intended` dla `startActivity` i `intending` dla `startActivityForResult`.
130+
Uruchomienie akcji następuje poprzez wyołanie metody `perform` klasy `ViewInteraction` lub `DataInteraction` w zależności od rodzaju elementu oraz przekazanie obiektów typu `ViewAction` jako argumentów. Akcje jakie można wykonać to m.in. `click`, `typeText`, `scrollTo`, `pressKey`, `clearText`. Ponadto jeśli podejmowana akcja dotyczy intencji (`Intent`) można wykorzystać zasadę `IntentsTestRule`, która waliduję intencje wysłane przez testowane aplikację oraz metody weryfikujące `intended` dla `startActivity` i `intending` dla `startActivityForResult`.
131131

132132
{% highlight kotlin %}
133133
@RunWith(AndroidJUnit4::class)
@@ -270,3 +270,11 @@ fun verifyPassedMessageFromScrollable() {
270270
else throw UiObjectNotFoundException("Throw when no matching UI element is found")
271271
}
272272
{% endhighlight %}
273+
274+
## Android Test Orchestrator
275+
Wykonywanie testów interfejsu użytkownika w Android od czasu do czasu narażone jest na występowanie błędów z niespodziewanym zatrzymanie całego zestawu testowego oraz ze wzajemnym nakrywaniem się testów (np. test się zakończył, ale żądane operacje w tle nadal trwa co może mieć wpływ na kolejne testy). Wykorzystanie mechanizmu `bezczynnych zasobów` (`idling resources`) pozwala w kontrolowany sposób przeprowadzić operacje asynchroniczną, której wyniki wpływają na kolejne operacje w teście co jednak nie rozwiązuje całkowicie wspomnianych problemów. Z pomocą przychodzi narzędzie `Android Test Orchestrator`, które umożliwia wykonanie każdego testu na własnej odseparowanej instancji `AndroidJUnitRunner`.
276+
277+
## Espresso Test Recorder
278+
Narzędzie `Espresso Test Recorder` umożliwia tworzenie testów UI w `Espresso` poprzez rejestrowanie akcji oraz tworzenie asercji w graficznym panelu bez ręcznego pisania kodu. Aby nagrać test należy w `Android Studio` wybrać opcję `Run/Record Espresso Test`, uruchomić aplikację na wskazanym urządzeniu lub emulatorze oraz ręcznie wykonać akcje użytkownika w aplikacji dodając asercje dla stanu widoków. Nagrany test można zapisać do nowej klasy testowej i uruchomić tak samo jak każdy test instrumentalny. Tworzenie testów przy pomocy Espresso Test Recorder jest powolne, a asercje ograniczone do weryfikowania tekstu i istnienia widoku.
279+
280+
![Nagrywanie testu](/assets/img/diagrams/testing/espresso_test_recorder.png){: .center-image }

_posts/testing/2018-12-31-proces_testowy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date: 2018-12-31
55
categories: ["Testowanie"]
66
image: testing/process
77
description: "Testowanie"
8-
keywords: "testowanie, testing, testy, proces, poziomy, jednostkowe, integracyjne, systemowe, akceptacyjne, manualne, automatyczne, lokalne, integracyjne, unit test, ui test, błąd, usterka, junit, jmeter, espresso, robolectric, android, programowanie, programming"
8+
keywords: "testowanie, testing, testy, proces, poziomy, jednostkowe, integracyjne, systemowe, akceptacyjne, manualne, automatyczne, lokalne, integracyjne, unit test, ui test, błąd, usterka, junit, jmeter, espresso, robolectric, crashlytics, android, programowanie, programming"
99
---
1010

1111
## Definicja
@@ -24,7 +24,7 @@ W celu wykrycia błędów w interfejsach oraz interakcjach pomiędzy integrowany
2424
`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 w `Android Studio` czy `jMeter`), 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.
2525

2626
## Testy akceptacyjne
27-
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` pozwala poznać błędy i lokalizować usterki co ułatwia naprawę popełnionych błędów.
27+
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.
2828

2929
## Wyzwania
3030
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.
Loading

0 commit comments

Comments
 (0)