Tester les activités de votre application

Les activités servent de conteneurs pour chaque interaction utilisateur dans votre application. Il est donc important de tester le comportement des activités de votre application lors d'événements au niveau de l'appareil, par exemple:

  • Une autre application, par exemple l'application pour téléphone de l'appareil, interrompt l'activité de votre application.
  • Le système détruit et recrée votre activité.
  • L'utilisateur place votre activité dans un nouvel environnement de fenêtrage, tel que Picture-in-picture (PIP) ou le mode multifenêtre.

En particulier, il est important de vous assurer que votre activité se comporte correctement en réponse aux événements décrits dans la section Cycle de vie d'une activité.

Ce guide explique comment évaluer la capacité de votre application à maintenir l'intégrité des données et une bonne expérience utilisateur lorsque ses activités passent par différents états de leur cycle de vie.

Contrôler l'état d'une activité

L'un des aspects clés du test des activités de votre application consiste à les placer dans des états particuliers. Pour définir cette partie "donnée" de vos tests, utilisez des instances de ActivityScenario, qui fait partie de la bibliothèque AndroidX Test. Elle vous permet de placer votre activité dans des états qui simulent des événements au niveau de l'appareil.

ActivityScenario est une API multiplate-forme qui peut être utilisée dans les tests unitaires locaux et les tests d'intégration sur l'appareil. Sur un appareil réel ou virtuel, ActivityScenario assure la sécurité des threads, en synchronisant les événements entre le thread d'instrumentation de votre test et le thread qui exécute votre activité testée.

L'API est particulièrement bien adaptée pour évaluer le comportement d'une activité testée lorsqu'elle est détruite ou créée. Cette section présente les cas d'utilisation les plus courants associés à cette API.

Créer une activité

Pour créer l'activité testée, ajoutez le code indiqué dans l'extrait suivant:

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

Une fois l'activité créée, ActivityScenario la fait passer à l'état RESUMED. Cet état indique que votre activité est en cours d'exécution et visible par les utilisateurs. Dans cet état, vous êtes libre d'interagir avec les éléments View de votre activité à l'aide des tests de l'interface utilisateur Espresso.

Google vous recommande d'appeler close sur l'activité une fois le test terminé. Cela nettoie les ressources associées et améliore la stabilité de vos tests. ActivityScenario implémente Closeable, ce qui vous permet d'appliquer l'extension use, ou try-with-resources dans le langage de programmation Java, afin que l'activité se ferme automatiquement.

Vous pouvez également utiliser ActivityScenarioRule pour appeler automatiquement ActivityScenario.launch avant chaque test et ActivityScenario.close lors de la suppression du test. L'exemple suivant montre comment définir une règle et obtenir une instance d'un scénario à partir de celle-ci:

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

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

Faire passer l'activité à un nouvel état

Pour modifier l'état de l'activité, par exemple CREATED ou STARTED, appelez moveToState(). Cette action simule une situation dans laquelle votre activité est respectivement interrompue ou mise en pause, car elle est interrompue par une autre application ou une action du système.

Un exemple d'utilisation de moveToState() apparaît dans l'extrait de code suivant:

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

Déterminer l'état actuel de l'activité

Pour déterminer l'état actuel d'une activité testée, obtenez la valeur du champ state dans votre objet ActivityScenario. Il est particulièrement utile de vérifier l'état d'une activité testée si celle-ci redirige vers une autre activité ou se termine elle-même, comme illustré dans l'extrait de code suivant:

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

Recréer l'activité

Lorsqu'un appareil manque de ressources, le système peut détruire une activité, ce qui oblige votre application à recréer cette activité lorsque l'utilisateur y retourne. Pour simuler ces conditions, appelez recreate():

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

La classe ActivityScenario gère l'état d'instance enregistré de l'activité et tous les objets annotés à l'aide de @NonConfigurationInstance. Ces objets sont chargés dans la nouvelle instance de l'activité testée.

Récupérer les résultats d'activités

Pour obtenir le code ou les données de résultat associés à une activité terminée, récupérez la valeur du champ result dans votre objet ActivityScenario, comme indiqué dans l'extrait de code suivant:

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

Déclencher des actions dans l'activité

Toutes les méthodes de ActivityScenario bloquent les appels. L'API nécessite donc que vous les exécutiez dans le thread d'instrumentation.

Pour déclencher des actions dans l'activité testée, utilisez les outils de mise en correspondance des vues Espresso pour interagir avec les éléments de votre vue:

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

Toutefois, si vous devez appeler une méthode sur l'activité elle-même, vous pouvez le faire en toute sécurité en implémentant ActivityAction:

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