Aktivitäten der App testen

Aktivitäten dienen als Container für jede Nutzerinteraktion in Ihrer App. Daher ist es wichtig, das Verhalten der Aktivitäten Ihrer App bei Ereignissen auf Geräteebene zu testen, z. B. bei folgenden:

  • Eine andere App, z. B. die Telefon App des Geräts, unterbricht die Aktivität Ihrer App.
  • Das System beendet und startet Ihre Aktivität neu.
  • Der Nutzer platziert Ihre Aktivität in einer neuen Fensterumgebung, z. B. im Bild-im-Bild-Modus (BiB) oder im Multi-Window-Modus.

Insbesondere ist es wichtig, dass sich Ihre Aktivität in Reaktion auf die in Der Aktivitätslebenszyklus beschriebenen Ereignisse korrekt verhält.

In diesem Leitfaden wird beschrieben, wie Sie die Fähigkeit Ihrer App bewerten können, die Datenintegrität und eine gute Nutzerfreundlichkeit aufrechtzuerhalten, wenn die Aktivitäten Ihrer App in ihren Lebenszyklen in verschiedene Status übergehen.

Status einer Aktivität ändern

Ein wichtiger Aspekt beim Testen der Aktivitäten Ihrer App ist, dass Sie die Aktivitäten in bestimmte Zustände versetzen. Um diesen „Given“-Teil Ihrer Tests zu definieren, verwenden Sie Instanzen von ActivityScenario, die Teil der AndroidX Test-Bibliothek sind. Mit dieser Klasse können Sie Ihre Aktivität in Zustände versetzen, die Geräteereignisse simulieren.

ActivityScenario ist eine plattformübergreifende API, die Sie sowohl in lokalen Unit-Tests als auch in On-Device-Integrationstests verwenden können. Auf einem echten oder virtuellen Gerät bietet ActivityScenario Threadsicherheit, indem Ereignisse zwischen dem Instrumentation-Thread Ihres Tests und dem Thread synchronisiert werden, in dem die zu testende Aktivität ausgeführt wird.

Die API eignet sich besonders gut, um zu bewerten, wie sich eine zu testende Aktivität verhält, wenn sie beendet oder erstellt wird. In diesem Abschnitt werden die häufigsten Anwendungsfälle für diese API beschrieben.

Aktivität erstellen

Fügen Sie den Code im folgenden Snippet hinzu, um die zu testende Aktivität zu erstellen:

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

Nachdem die Aktivität erstellt wurde, wird sie von ActivityScenario in den Status RESUMED versetzt. Dieser Status gibt an, dass Ihre Aktivität ausgeführt wird und für Nutzer sichtbar ist. In diesem Zustand können Sie mit den View-Elementen Ihrer Aktivität interagieren, indem Sie Espresso-UI-Tests verwenden.

Google empfiehlt, close für die Aktivität aufzurufen, wenn der Test abgeschlossen ist. Dadurch werden die zugehörigen Ressourcen bereinigt und die Stabilität Ihrer Tests verbessert. ActivityScenario implementiert Closeable. Sie können also die Erweiterung use oder try-with-resources in der Programmiersprache Java anwenden, damit die Aktivität automatisch geschlossen wird.

Alternativ können Sie ActivityScenarioRule verwenden, um ActivityScenario.launch vor jedem Test und ActivityScenario.close beim Test-Teardown automatisch aufzurufen. Im folgenden Beispiel wird gezeigt, wie eine Regel definiert und eine Instanz eines Szenarios daraus abgerufen wird:

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

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

Aktivität in einen neuen Status versetzen

Um die Aktivität in einen anderen Status zu versetzen, z. B. CREATED oder STARTED, rufen Sie moveToState() auf. Mit dieser Aktion wird eine Situation simuliert, in der deine Aktivität beendet oder pausiert wird, weil sie durch eine andere App oder eine Systemaktion unterbrochen wird.

Ein Beispiel für die Verwendung von moveToState() finden Sie im folgenden Code-Snippet:

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

Aktuellen Aktivitätsstatus ermitteln

Um den aktuellen Status einer zu testenden Aktivität zu ermitteln, rufen Sie den Wert des Felds state in Ihrem ActivityScenario-Objekt ab. Es ist besonders hilfreich, den Status einer Aktivität zu prüfen, die getestet wird, wenn die Aktivität zu einer anderen Aktivität weiterleitet oder sich selbst beendet, wie im folgenden Code-Snippet gezeigt:

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

Aktivität neu erstellen

Wenn auf einem Gerät nur noch wenige Ressourcen verfügbar sind, kann es vorkommen, dass das System eine Aktivität beendet. In diesem Fall muss Ihre App die Aktivität neu erstellen, wenn der Nutzer zu Ihrer App zurückkehrt. Rufen Sie recreate() auf, um diese Bedingungen zu simulieren:

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

Die Klasse ActivityScenario verwaltet den gespeicherten Instanzstatus der Aktivität und alle Objekte, die mit @NonConfigurationInstance annotiert sind. Diese Objekte werden in die neue Instanz der zu testenden Aktivität geladen.

Aktivitätsergebnisse abrufen

Wenn Sie den Ergebniscode oder die Daten einer abgeschlossenen Aktivität abrufen möchten, rufen Sie den Wert des Felds result in Ihrem ActivityScenario-Objekt ab, wie im folgenden Code-Snippet gezeigt:

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

Aktionen in der Aktivität auslösen

Alle Methoden in ActivityScenario sind blockierende Aufrufe. Daher müssen Sie sie im Instrumentation-Thread ausführen.

Verwenden Sie Espresso-View-Matcher, um Aktionen in der zu testenden Aktivität auszulösen und mit Elementen in der Ansicht zu interagieren:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.refresh)).perform(click())
        }
    }
}

Wenn Sie jedoch eine Methode für die Aktivität selbst aufrufen müssen, können Sie dies sicher tun, indem Sie ActivityAction implementieren:

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