Ressources inactives d'Espresso

Une ressource inactive représente une opération asynchrone dont les résultats ont une incidence sur les opérations ultérieures dans un test d'interface utilisateur. En enregistrant les ressources inactives avec Espresso, vous pouvez valider ces opérations asynchrones de manière plus fiable pour tester votre application.

Identifier les cas où les ressources inactives sont nécessaires

Espresso propose un ensemble sophistiqué fonctionnalités de synchronisation. Ce caractéristique du framework, mais ne s'applique qu'aux opérations messages sur MessageQueue, comme une sous-classe de View qui dessine son contenu à l'écran.

Comme Espresso n'a pas connaissance des autres opérations asynchrones, y compris s'exécutant sur un thread en arrière-plan, Espresso ne peut pas assurer la synchronisation garanties dans ces situations. Pour permettre à Espresso de connaître l'état les opérations de longue durée, vous devez enregistrer chacune d'entre elles en tant que ressource inactive.

Si vous n'utilisez pas de ressources inactives lorsque vous testez les résultats de l'API le travail asynchrone, vous devrez peut-être utiliser l'une des des solutions alternatives pour améliorer vos tests fiabilité:

  • Ajout d'appels à Thread.sleep(). Lorsque vous des retards artificiels sur vos tests, la suite de tests prend plus de temps terminer son exécution et il peut arriver que vos tests échouent parfois lorsqu'ils sont exécutés sur les appareils plus lents. De plus, ces retards n'évoluent pas bien, car votre application pourrait vous devrez effectuer des tâches asynchrones plus longues dans une prochaine version.
  • Implémenter des wrappers de nouvelle tentative,qui utilisent une boucle pour vérifier de manière répétée votre application continue d'exécuter des tâches asynchrones jusqu'à expiration d'un délai. Même si vous spécifiez un nombre maximal de nouvelles tentatives dans vos tests, chaque réexécution consomme les ressources système, en particulier le CPU.
  • Utiliser des instances de CountDownLatch,qui permettent à un ou plusieurs threads d'attendre qu'un nombre spécifique d'opérations soit atteint exécutées dans un autre thread sont terminées. Ces objets nécessitent que vous spécifiiez un délai avant expiration sinon votre application risque d'être bloquée indéfiniment. Loquet compliquent inutilement votre code, ce qui complique la maintenance.

Espresso vous permet de supprimer ces solutions de contournement non fiables de vos tests. enregistrez plutôt le travail asynchrone de votre application en tant que ressources inactives.

Cas d'utilisation courants

Lorsque vous effectuez des opérations semblables aux exemples suivants dans vos tests, envisagez d'utiliser une ressource d'inactivité:

  • charger des données à partir d'Internet ou d'une source de données locale ;
  • Établir des connexions avec des bases de données et des rappels.
  • Gestion des services, à l'aide d'un service système ou d'une instance de IntentService
  • Exécuter une logique métier complexe, telle que des transformations bitmap

Il est particulièrement important d'enregistrer les ressources inactives lorsque ces opérations mettre à jour une UI que vos tests valident.

Exemples d'implémentations de ressources inactives

La liste suivante décrit plusieurs exemples d'implémentations de ressources inactives que vous pouvez intégrer à votre application:

CountingIdlingResource
Maintien d'un compteur de tâches actives. Lorsque le compteur est égal à zéro, la valeur est considérée comme inactive. Cette fonctionnalité est très semblable à celle Semaphore Dans la plupart des cas, cette implémentation suffisant pour gérer le travail asynchrone de votre application pendant les tests.
UriIdlingResource
Semblable à CountingIdlingResource, Toutefois, le compteur doit être égal à zéro pendant une période spécifique, avant que est considérée comme inactive. Ce délai d'attente supplémentaire prend des de requêtes réseau, lorsqu'une application de votre thread peut effectuer une nouvelle immédiatement après avoir reçu une réponse à une requête précédente.
IdlingThreadPoolExecutor
Implémentation personnalisée de ThreadPoolExecutor qui garde la trace du nombre total de tâches en cours d'exécution dans le thread créé des pools d'objets. Cette classe utilise CountingIdlingResource jusqu'à et maintenir le compteur de tâches actives.
IdlingScheduledThreadPoolExecutor
Implémentation personnalisée de ScheduledThreadPoolExecutor Elle fournit le même et ses capacités en tant que IdlingThreadPoolExecutor cours, mais il peut également garder une trace des tâches planifiées ou dont l'exécution est planifiée à intervalles réguliers.

Créer votre propre ressource d'inactivité

Lorsque vous utilisez des ressources inactives dans les tests de votre application, vous devrez peut-être fournir la gestion personnalisée des ressources ou la journalisation. Dans ce cas, les implémentations répertoriés dans la section précédente peuvent ne pas suffire. Dans ce cas, vous pouvez étendre l'une de ces implémentations de ressources inactives ou créer la vôtre.

Si vous implémentez votre propre fonctionnalité de ressource d'inactivité, conservez les pratiques, en particulier la première:

Appeler les transitions vers l'état d'inactivité en dehors des vérifications d'inactivité.
Une fois votre application inactive, appelez onTransitionToIdle() en dehors de toute implémentation isIdleNow() De cette façon, Espresso n'effectue pas de vérification inutile pour déterminer si une valeur la ressource "idling" est inactive.

L'extrait de code suivant illustre cette recommandation:

Kotlin

fun isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

fun backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}

Java

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
Enregistrez les ressources inactives avant d'en avoir besoin.

Les avantages de la synchronisation associés aux ressources inactives ne prennent effet après le premier appel d'Espresso de la commande isIdleNow().

La liste suivante présente plusieurs exemples de cette propriété:

  • Si vous enregistrez une ressource inactive dans une méthode annotée avec @Before, la ressource d'inactivité prend effet à la première ligne de chaque test.
  • Si vous enregistrez une ressource d'inactivité dans un test, la ressource d'inactivité prend effet lors de l'action suivante basée sur Espresso. Ce comportement est encore se produit même si l'action suivante se trouve dans le même test que l'affirmation qui enregistre la ressource d'inactivité.
Annuler l'enregistrement des ressources inactives une fois que vous avez fini de les utiliser

Pour préserver les ressources système, annulez l'enregistrement des ressources inactives dès que possible car vous n’en avez plus besoin. Par exemple, si vous enregistrez une ressource inactive dans une méthode annotée avec @Before, il est préférable d'annuler l'enregistrement de cette ressource dans un la méthode correspondante annotée avec @After.

Utilisez un registre d'inactivité pour enregistrer et annuler l'enregistrement des ressources inactives.

En utilisant ce conteneur pour les ressources d'inactivité de votre application, vous pouvez enregistrer et désenregistrer les ressources inactives de manière répétée selon les besoins, tout en observant des comportemental.

Ne gérer qu'un état d'application simple au sein des ressources inactives

Par exemple, les ressources inactives que vous implémentez et enregistrez ne doivent pas qui contiennent des références aux objets View.

Enregistrer les ressources inactives

Espresso fournit une classe de conteneur dans laquelle vous pouvez placer le paramètre d'inactivité de votre application. ressources. Cette classe, appelée IdlingRegistry, est un un artefact autonome qui introduit un minimum de surcharge pour votre application. La classe vous pouvez également prendre les mesures suivantes pour améliorer les performances la facilité de gestion:

  • Créez une référence à IdlingRegistry au lieu des ressources inactives. qu'il contient, dans les tests de votre application.
  • Conservez des différences dans la collecte des ressources inactives que vous utilisez pour chaque variante de compilation.
  • Définissez les ressources inactives dans les services de votre application plutôt que dans l'UI qui font référence à ces services.

Intégrer des ressources inactives dans votre application

Bien qu'il soit possible d'ajouter des ressources inactives à une application de différentes manières, en particulier l'encapsulation de votre application tout en permettant de spécifier une opération particulière représentée par une ressource d'inactivité donnée.

Lorsque vous ajoutez des ressources inactives dans votre application, nous vous recommandons vivement de placer le paramètre la logique de ressource inactive dans l'application elle-même, et n'effectuer que l'enregistrement et les opérations de désinscription dans vos tests.

Bien que vous créiez la situation inhabituelle d'utiliser une interface de test uniquement dans code de production à l'aide de cette approche, vous pouvez encapsuler les ressources inactives dont vous disposez déjà, tout en conservant la taille de l'APK et le nombre de méthodes de votre application.

Autres approches

Si vous préférez ne pas avoir de logique de ressources inactives dans la production de votre application il existe plusieurs autres stratégies d'intégration viables:

  • Créez des variantes de compilation, telles que produit types, et n'utilisez les ressources d'inactivité que dans la version de débogage de votre application.
  • Utilisez un framework d'injection de dépendances comme Dagger pour injecter le paramètre d'inactivité de votre application. graphique des dépendances des ressources dans vos tests. Si vous utilisez Dagger 2, la l'injection elle-même doit provenir d'un sous-composant.
  • Implémentez une ressource d'inactivité dans les tests de votre application et exposez la partie de l'implémentation de votre application qui doivent être synchronisées dans ces tests.

    Attention : Bien que cette décision de conception semble créer une référence autonome aux ressources inactives, elle rompt également encapsulation dans toutes les applications, sauf les plus simples.

Ressources supplémentaires

Pour en savoir plus sur l'utilisation d'Espresso lors des tests sur Android, consultez le les ressources suivantes.

Exemples