Aktywności służą jako kontenery na każdą interakcję użytkownika w aplikacji, dlatego ważne jest, aby sprawdzać, jak te działania zachowują się w trakcie zdarzeń na poziomie urządzenia, takich jak:
- Inna aplikacja, na przykład aplikacja Telefon na urządzeniu, przerywa aktywność w aplikacji.
- System niszczy i odtwarza Twoją aktywność.
- Użytkownik umieści Twoją aktywność w nowym środowisku okiennym, takim jak obraz w obrazie (PIP) lub wiele okien.
W szczególności musisz się upewnić, że aktywność działa prawidłowo w odpowiedzi na zdarzenia opisane w artykule Cykl życia aktywności.
Z tego przewodnika dowiesz się, jak ocenić zdolność aplikacji do zachowania integralności danych i zapewniania użytkownikom dobrych wrażeń, gdy działania aplikacji przechodzą przez różne stany w cyklu życia.
Dysk o stanie aktywności
Jednym z kluczowych aspektów testowania aktywności w aplikacji jest umieszczanie jej w konkretnych stanach. Aby zdefiniować tę „daną” część testów, użyj wystąpień narzędzia ActivityScenario
, które wchodzi w skład biblioteki AndroidX Test. Za pomocą tych zajęć możesz przypisywać aktywności do stanów symulujących zdarzenia na poziomie urządzenia.
ActivityScenario
to wieloplatformowy interfejs API, którego można używać zarówno w testach jednostkowych lokalnych, jak i testach integracji na urządzeniu. Na prawdziwym lub wirtualnym urządzeniu ActivityScenario
zapewnia bezpieczeństwo wątków, synchronizuje zdarzenia między wątkiem narzędziowym testu a wątkiem, w którym testowana jest Twoja aktywność.
Interfejs API jest szczególnie przydatny do oceny zachowania testowanej aktywności po jej zniszczeniu lub utworzeniu. W tej sekcji przedstawiamy najczęstsze przypadki użycia związane z tym interfejsem API.
Utwórz aktywność
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
przenosi ją do stanu RESUMED
. Ten stan oznacza, że aktywność jest aktywna i widoczna dla użytkowników. W tym stanie możesz wchodzić w interakcje z elementami View
swojej aktywności za pomocą testów interfejsu Espresso.
Google zaleca wywołanie metody close
po zakończeniu testu. Oczyszcza to powiązane zasoby i zwiększa 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ć metody ActivityScenarioRule
, aby automatycznie wywoływać metodę ActivityScenario.launch
przed każdym testem i ActivityScenario.close
w przypadku dezaktywacji testu. Z przykładu poniżej dowiesz się, jak zdefiniować regułę i wybrać z niej scenariusz:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>() @Test fun testEvent() { val scenario = activityScenarioRule.scenario } }
Ustawianie nowego stanu aktywności
Aby zmienić stan aktywności, np. CREATED
lub STARTED
, wywołaj moveToState()
. Symuluje to sytuację, w której aktywność zostaje wstrzymana lub wstrzymana przez inną aplikację lub działanie systemowe.
Przykład użycia uprawnienia moveToState()
znajdziesz we 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
. Szczególnie przydatne jest sprawdzenie stanu testowanej aktywności, czy przekierowuje ona użytkownika do innej aktywności lub kończy działanie, 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 } } }
Powtórz zadanie
Gdy na urządzeniu brakuje zasobów, system może zniszczyć aktywność i wymagać od aplikacji jej odtworzenia po powrocie użytkownika 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
zachowuje zapisany stan instancji aktywności i wszystkie obiekty oznaczone za pomocą @NonConfigurationInstance
. Obiekty te wczytują się do nowej instancji testowanej aktywności.
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 } } }
Aktywowanie działań w aktywności
Wszystkie metody w ActivityScenario
blokują wywołania, więc interfejs API wymaga ich uruchomienia w wątku instrumentacji.
Aby aktywować działania w testowanej aktywności, użyj funkcji dopasowywania widoków 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 chcesz wywoływać metodę w samej aktywności, możesz to bezpiecznie zrobić, implementując ActivityAction
:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }