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, tels que les suivants :

  • Une autre application, telle que l'application 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 le mode Picture-in-picture (PIP) ou le mode multifenêtre.

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

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

Tester les activités dans Compose

Lorsque vous testez une application créée avec Jetpack Compose, vous utilisez généralement createAndroidComposeRule pour lancer votre activité et interagir avec vos composants d'interface utilisateur.

Toutefois, pour tester les événements au niveau de l'appareil, tels que les modifications de configuration ou l'activité mise en arrière-plan ou détruite par le système, vous devez manipuler directement le cycle de vie de l'activité. Pour ce faire, utilisez le framework ActivityScenario sous-jacent.

La règle de test Compose encapsule et gère automatiquement ce scénario pour vous. Tout au long de ce guide, vous verrez le modèle suivant utilisé pour combler le fossé entre les tests d'UI modernes et la gestion standard du cycle de vie :

@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()

@Test fun testEvent() {
    val scenario = composeTestRule.activityRule.scenario

    // ...
}

Gérer l'état d'une activité

Un aspect clé du test des activités de votre application consiste à placer les activités de votre application dans des états particuliers. Pour définir cette partie "étant donné" de vos tests, utilisez des instances de ActivityScenario, qui font partie de la bibliothèque AndroidX Test. À l'aide de cette classe, vous pouvez placer votre activité dans des états qui simulent des événements au niveau de l'appareil.

ActivityScenario est une API multiplate-forme que vous pouvez utiliser 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é en cours de test.

L'API est particulièrement 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é à tester, 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 composables de votre activité à l'aide des API de test Compose.

Google vous recommande d'appeler close sur l'activité une fois le test terminé. Cela permet de nettoyer les ressources associées et d'améliorer la stabilité de vos tests. ActivityScenario implémente Closeable. Vous pouvez donc appliquer l'extension use pour que l'activité se ferme automatiquement.

Vous pouvez également utiliser createAndroidComposeRule pour lancer automatiquement l'Activity avant chaque test, gérer l'arrêt et vous donner accès aux méthodes de test de l'UI Compose et à ActivityScenario sous-jacent. L'exemple suivant montre comment définir une règle et obtenir une instance de scénario à partir de celle-ci :

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule
    val composeTestRule = createAndroidComposeRule<MyActivity>()

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

Faire passer l'activité à un nouvel état

Pour que l'activité passe à un état différent, tel que CREATED ou STARTED, appelez moveToState. Cette action simule une situation dans laquelle votre activité est respectivement arrêtée ou mise en pause, car elle est interrompue par une autre application ou une action 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é en cours de test, obtenez la valeur du champ state dans votre objet ActivityScenario. Il est particulièrement utile de vérifier l'état d'une activité en cours de test si elle redirige vers une autre activité ou se termine elle-même, comme le montre 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 revient. Pour simuler ces conditions, appelez recreate :

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

La classe ActivityScenario conserve l'état d'instance enregistré de l'activité et tous les objets annotés à l'aide de @NonConfigurationInstance. Ces objets se chargent dans la nouvelle instance de votre activité en cours de test.

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

Pour obtenir le code de résultat ou les données associées à une activité terminée, récupérez la valeur du champ result dans votre objet ActivityScenario. À l'aide de createAndroidComposeRule, vous pouvez facilement déclencher l'action d'interface utilisateur qui termine l'activité, comme indiqué dans l'extrait de code suivant :

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule
    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @Test fun testResult() {
        composeTestRule.onNodeWithTag("finish_button").performClick()

        val scenario = composeTestRule.activityRule.scenario
        val resultCode = scenario.result.resultCode
        val resultData = scenario.result.resultData
    }
}

Déclencher des actions dans l'activité

Toutes les méthodes de ActivityScenario sont des appels bloquants. L'API vous demande donc de les exécuter dans le thread d'instrumentation.

Pour déclencher des actions dans votre activité testée, utilisez les API de test Compose pour interagir avec vos composables :

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule
    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @Test fun testEvent() {
        composeTestRule.onNodeWithText("Refresh").performClick()
    }
}

Si vous devez appeler une méthode sur l'activité elle-même, vous pouvez le faire en toute sécurité à l'aide de onActivity :

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

Ressources supplémentaires

Pour en savoir plus sur les tests, consultez les ressources supplémentaires suivantes :

Documentation