Działania służą jako kontenery dla każdej interakcji użytkownika w aplikacji, dlatego ważne jest, aby przetestować, jak zachowują się działania aplikacji podczas zdarzeń na poziomie urządzenia, takich jak:
- Inna aplikacja, np. aplikacja Telefon na urządzeniu, przerywa działanie Twojej aplikacji.
- System usuwa i ponownie tworzy Twoją aktywność.
- Użytkownik umieszcza Twoją aktywność w nowym środowisku okienkowym, np. w trybie obraz w obrazie lub w trybie wielu okien.
W szczególności ważne jest, aby Twoja aktywność działała prawidłowo w odpowiedzi na zdarzenia opisane w artykule Cykl życia aktywności.
Ten przewodnik opisuje, jak ocenić zdolność aplikacji do zachowania integralności danych i zapewnienia dobrej jakości obsługi użytkownika w miarę przechodzenia działań aplikacji przez różne stany w ich cyklach życia.
Określanie stanu aktywności
Jednym z kluczowych aspektów testowania aktywności aplikacji jest umieszczanie ich w określonych stanach. Aby zdefiniować tę część testów, użyj instancji ActivityScenario, która jest częścią biblioteki AndroidX Test. Za pomocą tej klasy możesz umieszczać aktywność w stanach symulujących zdarzenia na poziomie urządzenia.
ActivityScenario to wieloplatformowy interfejs API, którego możesz używać zarówno w lokalnych testach jednostkowych, jak i w testach integracyjnych na urządzeniu. Na urządzeniu rzeczywistym lub wirtualnym ActivityScenario zapewnia bezpieczeństwo wątków, synchronizując zdarzenia między wątkiem instrumentacji testu a wątkiem, w którym działa testowana aktywność.
Interfejs API szczególnie dobrze nadaje się do oceny zachowania testowanego działania po jego zniszczeniu lub utworzeniu. W tej sekcji przedstawiamy najczęstsze przypadki użycia tego interfejsu API.
Tworzenie działania
Aby utworzyć testowaną aktywność, dodaj kod widoczny w tym fragmencie:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { } } }
Po utworzeniu aktywności ActivityScenario przechodzi ona w stan RESUMED. Ten stan oznacza, że Twoja aktywność jest uruchomiona i widoczna dla użytkowników. W tym stanie możesz wchodzić w interakcję z elementami aktywnościView za pomocą testów interfejsu Espresso.
Google zaleca, aby po zakończeniu testu zadzwonić pod numer close. Uporządkuje to powiązane zasoby i zwiększy stabilność testów. ActivityScenario implementuje Closeable, więc możesz zastosować rozszerzenie use lub try-with-resources w języku programowania Java, aby aktywność zamykała się automatycznie.
Możesz też użyć ActivityScenarioRule, aby automatycznie wywoływać ActivityScenario.launch przed każdym testem i ActivityScenario.close po zakończeniu testu. Poniższy przykład pokazuje, jak zdefiniować regułę i uzyskać z niej instancję scenariusza:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>() @Test fun testEvent() { val scenario = activityScenarioRule.scenario } }
Przenoszenie aktywności do nowego stanu
Aby zmienić stan aktywności, np. na CREATED lub STARTED, wywołaj
moveToState(). Ta czynność symuluje sytuację, w której Twoja aktywność jest zatrzymana lub wstrzymana, ponieważ została przerwana przez inną aplikację lub działanie systemu.
Przykładowe użycie moveToState() znajdziesz w tym fragmencie kodu:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.moveToState(State.CREATED) } } }
Określanie bieżącego stanu aktywności
Aby określić bieżący stan testowanej aktywności, pobierz wartość pola state w obiekcie ActivityScenario. Jest to szczególnie przydatne, gdy sprawdzasz stan testowanej aktywności, która przekierowuje do innej aktywności lub sama się kończy, jak pokazano w tym fragmencie kodu:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> startActivity(Intent(activity, MyOtherActivity::class.java)) } val originalActivityState = scenario.state } } }
Ponowne utworzenie aktywności
Gdy na urządzeniu brakuje zasobów, system może zniszczyć aktywność, co wymaga od aplikacji ponownego utworzenia tej aktywności, gdy użytkownik wróci do aplikacji. Aby zasymulować te warunki, wywołaj recreate():
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.recreate() } } }
Klasa ActivityScenario utrzymuje zapisany stan instancji aktywności i wszystkie obiekty oznaczone adnotacjami za pomocą @NonConfigurationInstance. Te obiekty są wczytywane do nowej instancji testowanego działania.
Pobieranie wyników aktywności
Aby uzyskać kod wyniku lub dane powiązane z zakończoną aktywnością, pobierz wartość pola result w obiekcie ActivityScenario, jak pokazano w tym fragmencie kodu:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testResult() { launchActivity<MyActivity>().use { onView(withId(R.id.finish_button)).perform(click()) // Activity under test is now finished. val resultCode = scenario.result.resultCode val resultData = scenario.result.resultData } } }
Wywoływanie działań w aktywności
Wszystkie metody w ActivityScenario to wywołania blokujące, więc interfejs API wymaga uruchamiania ich w wątku instrumentacji.
Aby wywołać działania w testowanej aktywności, użyj dopasowań widoku Espresso do interakcji z elementami w widoku:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { onView(withId(R.id.refresh)).perform(click()) } } }
Jeśli jednak musisz wywołać metodę w samej aktywności, możesz to zrobić bezpiecznie, implementując ActivityAction:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }