Aktivitäten der App testen

Aktivitäten dienen als Container für jede Nutzerinteraktion in Ihrer App. Daher ist es wichtig, zu testen, wie sich die Aktivitäten Ihrer App bei Ereignissen auf Geräteebene verhalten. Hier einige Beispiele:

  • Eine andere App, z. B. die Telefon-App des Geräts, unterbricht die Aktivitäten Ihrer App.
  • Das System zerstört Ihre Aktivitäten und reproduziert sie wieder.
  • Der Nutzer platziert Ihre Aktivität in einer neuen Windowing-Umgebung, z. B. Bild-im-Bild (BiB) oder Mehrfenstermodus.

Insbesondere müssen Sie dafür sorgen, dass sich Ihre Aktivität als Reaktion auf die unter Aktivitätslebenszyklus beschriebenen Ereignisse korrekt verhält.

In diesem Leitfaden wird beschrieben, wie Sie die Fähigkeit Ihrer Anwendung bewerten, die Datenintegrität und Nutzerfreundlichkeit aufrechtzuerhalten, wenn die Aktivitäten Ihrer Anwendung verschiedene Status in ihrem Lebenszyklus durchlaufen.

Status einer Aktivität Drive

Ein wichtiger Aspekt beim Testen der App-Aktivitäten ist das Platzieren der App-Aktivitäten in bestimmten Status. Um diesen „angegebenen“ Teil der Tests zu definieren, verwende Instanzen von ActivityScenario, der Teil der Bibliothek AndroidX Test ist. Mit dieser Klasse kannst du deine Aktivitäten in Stadien platzieren, die Ereignisse auf Geräteebene simulieren.

ActivityScenario ist eine plattformübergreifende API, die Sie sowohl für lokale Unittests als auch für Integrationstests auf dem Gerät verwenden können. Auf einem echten oder virtuellen Gerät bietet ActivityScenario Thread-Sicherheit und synchronisiert Ereignisse zwischen dem Instrumentierungsthread Ihres Tests und dem Thread, der Ihre zu testende Aktivität ausführt.

Die API eignet sich besonders gut zum Auswerten des Verhaltens einer zu testenden Aktivität, wenn sie gelöscht oder erstellt wird. In diesem Abschnitt werden die häufigsten Anwendungsfälle für diese API vorgestellt.

Aktivität erstellen

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

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

Nach dem Erstellen der Aktivität setzt ActivityScenario die Aktivität in den Status RESUMED um. Dieser Status zeigt an, dass Ihre Aktivität ausgeführt wird und für Nutzer sichtbar ist. In diesem Status können Sie mithilfe von Espresso-UI-Tests kostenlos mit den View-Elementen Ihrer Aktivität interagieren.

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

Alternativ können Sie ActivityScenarioRule verwenden, um ActivityScenario.launch vor jedem Test automatisch und ActivityScenario.close beim Teardown von Tests aufzurufen. Das folgende Beispiel zeigt, wie Sie eine Regel definieren und daraus eine Instanz eines Szenarios abrufen:

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

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

Aktivität auf einen neuen Status bringen

Wenn Sie die Aktivität in einen anderen Status verschieben möchten, z. B. CREATED oder STARTED, rufen Sie moveToState() auf. Diese Aktion simuliert eine Situation, in der Ihre Aktivität beendet bzw. pausiert wird, da sie von einer anderen Anwendung oder einer Systemaktion unterbrochen wird.

Im folgenden Code-Snippet wird ein Beispiel für die Verwendung von moveToState() angezeigt:

@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 zu testenden Aktivität zu überprüfen, wenn die Aktivität zu einer anderen Aktivität weiterleitet oder von selbst beendet wird, 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 ein Gerät nur noch wenig Ressourcen hat, löscht das System möglicherweise eine Aktivität. Daher muss Ihre App diese 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 mit einer abgeschlossenen Aktivität verknüpften Daten 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 blockieren Aufrufe, daher müssen Sie sie für die API im Instrumentierungsthread ausführen.

Um Aktionen in der zu testenden Aktivität auszulösen, verwenden Sie Espresso-View-Matcher, um 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 bedenkenlos durch Implementierung von ActivityAction tun:

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