Testowanie aktywności w aplikacji

Aktywności to kontenery dla każdej interakcji użytkownika w aplikacji, warto przetestować, jak aktywność w aplikacji zachowuje się na poziomie urządzenia zdarzenia, takie jak:

  • Inna aplikacja, np. aplikacja Telefon na urządzeniu, przerywa jej działanie.
  • System niszczy i tworzy Twoją aktywność.
  • użytkownik umieszcza Twoją aktywność w nowym środowisku okien, takim jak obraz w obrazie (PIP) lub wiele okien.

Ważne jest przede wszystkim prawidłowe zachowanie Twojej aktywności w reakcji na zdarzenia opisane w sekcji Działanie cyklu życia usługi.

Z tego przewodnika dowiesz się, jak ocenić zdolność aplikacji do utrzymania danych integralność i wygoda podczas korzystania z aplikacji przez różne stany w swoich cyklach życia.

Pokazuj stan aktywności

Jednym z kluczowych aspektów testowania aktywności w aplikacji jest dodanie w konkretnych stanach. Definiowanie tego słowa kluczowego do części testów, użyj funkcji wystąpienia ActivityScenario, części Biblioteka AndroidX Test. Korzystając z tych zajęć: umieszczać swoją aktywność w stanach, które symulują zdarzenia na poziomie urządzenia.

ActivityScenario to wieloplatformowy interfejs API, którego możesz używać w lokalnych testach jednostkowych oraz przeprowadzanie testów integracji na urządzeniu. Na prawdziwym lub wirtualnym urządzeniu ActivityScenario zapewnia bezpieczeństwo wątków, synchronizując zdarzenia między z wątkiem instrumentacji testu i wątkiem, w którym uruchamiasz testowaną aktywność.

Interfejs API szczególnie dobrze nadaje się do oceny, jak działa po zniszczeniu lub utworzeniu. W tej sekcji omawiamy najczęstsze przypadków użycia powiązanych 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 RESUMED stan. Ten stan oznacza, że aktywność jest aktywna widoczne dla użytkowników. W tym stanie możesz wchodzić w interakcje z View elementów za pomocą testów interfejsu Espresso.

Google zaleca wywołanie metody close podczas testu . Pozwoli to wyczyścić powiązane zasoby i poprawić stabilności testów. ActivityScenario implementuje Closeable, więc możesz zastosuj rozszerzenie use lub try-with-resources w programowaniu w Javie dzięki czemu działanie zakończy się automatycznie.

Możesz też użyć aplikacji ActivityScenarioRule, aby automatycznie zadzwonić ActivityScenario.launch przed każdym testem i ActivityScenario.close w momencie zakończenia testów. Poniższy przykład pokazuje, jak zdefiniować regułę i uzyskać dla danego przykładu:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

    @Test fun testEvent() {
        val scenario = activityScenarioRule.scenario
    }
}

Przenieś aktywność do nowego stanu

Aby ustawić inny stan aktywności, na przykład CREATED lub STARTED, wywołaj moveToState() To działanie symuluje sytuację, w której zatrzymana lub wstrzymana, ponieważ została przerwana przez inną aplikację lub działania systemowego.

Przykład użycia moveToState() jest widoczny 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ść state w obiekcie ActivityScenario. Szczególnie przydatne są aby sprawdzić stan testowanej aktywności, jeśli przekierowuje ona użytkowników na adres inne działanie lub samo się kończy, co pokazano w poniższym kodzie snippet:

@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
        }
    }
}

Odtwórz aktywność

Gdy na urządzeniu brakuje zasobów, system może zniszczyć aktywność, wymaga od aplikacji ponownego odtwarzania tej aktywności, gdy użytkownik powróci do aplikacji. Aby przeprowadzić symulację tych warunków, zadzwoń pod numer recreate():

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.recreate()
        }
    }
}

Klasa ActivityScenario zachowuje zapisany stan instancji aktywności i dowolne obiekty opatrzone adnotacjami za pomocą funkcji @NonConfigurationInstance. Te obiekty są wczytywane do nowego wystąpienia testowanej aktywności.

Pobieranie wyników aktywności

Aby uzyskać kod wyniku lub dane powiązane z zakończoną aktywnością, pobierz kod wartości pola result w obiekcie ActivityScenario, jak widać na stronie ten fragment 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
        }
    }
}

Aktywuj działania w działaniu

Wszystkie metody w ActivityScenario blokują wywołania, więc interfejs API wymaga aby uruchomić je w wątku instrumentacji.

Aby aktywować działania w teście testowym, użyj dopasowywania widoków Espresso do wchodzić w interakcję 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 tag ActivityAction:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
}