Écrire un lanceur de test Tradefed

Cette page explique comment écrire un nouveau lanceur de test dans Tradefed.

Arrière-plan

Pour en savoir plus sur la place des exécuteurs de test dans l'architecture Tradefed, consultez la section Structure d'un exécuteur de test.

Il ne s'agit pas d'une condition préalable à l'écriture d'un nouveau lanceur de tests. Les lanceurs de tests peuvent être écrits de manière isolée.

Minimum: implémenter l'interface

Le minimum requis pour être qualifié de lanceur de test Tradefed consiste à implémenter l'interface IRemoteTest et plus précisément la méthode run(TestInformation testInfo, ITestInvocationListener listener).

Cette méthode est celle appelée par le harnais lorsque vous utilisez l'exécuteur de test, semblable à un Runnable Java.

Chaque partie de cette méthode est considérée comme faisant partie de l'exécution du lanceur de test.

Rapporter les résultats du testeur

La méthode run de l'interface de base permet d'accéder à un objet d'écouteur de type ITestInvocationListener. Cet objet est essentiel pour générer des rapports sur les résultats structurés du lanceur de test vers le harnais.

En fournissant des résultats structurés, un outil d'exécution de test présente les propriétés suivantes:

  • Fournissez une liste appropriée de tous les tests exécutés, de la durée de leur exécution et de leur état (réussite, échec ou autre).
  • Métriques de rapport associées aux tests, le cas échéant, par exemple les métriques de temps d'installation.
  • S'adapter à la plupart des outils d'infrastructure, par exemple afficher des résultats et des métriques, etc.
  • Il est généralement plus facile à déboguer, car il existe une trace plus précise de l'exécution.

Toutefois, la création de rapports sur les résultats structurés est facultative. Un exécuteur de test peut simplement vouloir évaluer l'état de l'ensemble de l'exécution comme "PASSED" (RÉUSSI) ou "FAILED" (ÉCHEC) sans aucun détail sur l'exécution réelle.

Les événements suivants peuvent être appelés sur l'écouteur pour informer le harnais de la progression actuelle des exécutions:

  • testRunStarted: informe du début d'un groupe de scénarios de test associés.
    • testStarted: informe du début d'un cas de test.
    • testFailed/testIgnored: signalez le changement d'état du scénario de test en cours. Un cas de test sans changement d'état est considéré comme réussi.
    • testEnded: signale la fin du scénario de test.
  • testRunFailed: indique que l'état global de l'exécution du groupe de cas de test est un échec. Une exécution de test peut être un succès ou un échec indépendamment des résultats des cas de test, en fonction de ce que l'exécution attendait. Par exemple, un binaire exécutant plusieurs scénarios de test peut signaler tous les scénarios de test réussis, mais avec un code de sortie d'erreur (pour une raison quelconque: fuite de fichiers, etc.).
  • testRunEnded: informe de la fin du groupe de scénarios de test.

Il incombe à l'implémentateur du lanceur de tests de gérer et de s'assurer de l'ordre correct des rappels, par exemple en veillant à ce que testRunEnded soit appelé en cas d'exception à l'aide d'une clause finally.

Les rappels des cas de test (testStarted, testEnded, etc.) sont facultatifs. Une exécution de test peut se produire sans scénario de test.

Vous remarquerez peut-être que cette structure d'événements est inspirée de la structure JUnit typique. C'est intentionnel pour que les choses restent proches d'un élément de base que les développeurs connaissent généralement.

Journaliser les rapports à partir du programme d'exécution des tests

Si vous écrivez votre propre classe ou exécuteur de test Tradefed, vous implémenterez IRemoteTest et obtiendrez un ITestInvocationListener via la méthode run(). Cet écouteur peut être utilisé pour consigner des fichiers comme suit:

    listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);

Tester avec un appareil

L'interface minimale ci-dessus permet d'exécuter des tests très simples, isolés et ne nécessitant aucune ressource particulière, par exemple des tests unitaires Java.

Les rédacteurs de tests qui souhaitent passer à l'étape suivante des tests d'appareil auront besoin des interfaces suivantes:

  • IDeviceTest permet de recevoir l'objet ITestDevice qui représente l'appareil en cours de test et fournit l'API pour interagir avec lui.
  • IBuildReceiver permet au test d'obtenir l'objet IBuildInfo créé à l'étape build provider (Fournisseur de compilation) contenant toutes les informations et tous les artefacts liés à la configuration du test.

Les outils d'exécution de test s'intéressent généralement à ces interfaces afin d'obtenir des artefacts liés à l'exécution, par exemple des fichiers supplémentaires, et d'obtenir l'appareil testé qui sera ciblé lors de l'exécution.

Tester avec plusieurs appareils

Tradefed permet d'exécuter des tests sur plusieurs appareils en même temps. Cela est utile lorsque vous testez des composants qui nécessitent une interaction externe, comme un téléphone et l'association d'une montre.

Pour écrire un outil d'exécution de test pouvant utiliser plusieurs appareils, vous devez implémenter IMultiDeviceTest, qui vous permettra de recevoir une carte de ITestDevice à IBuildInfo contenant la liste complète des représentations d'appareils et les informations de compilation associées.

Le setter de l'interface est toujours appelé avant la méthode run. Il est donc possible de supposer que la structure sera disponible lorsque run sera appelé.

Tests conscients de leurs configurations

Certaines implémentations de lanceur de test peuvent avoir besoin d'informations sur la configuration globale pour fonctionner correctement, par exemple des métadonnées sur l'appel, ou sur l'target_preparer exécutée précédemment, etc.

Pour ce faire, un exécuteur de test peut accéder à l'objet IConfiguration dont il fait partie et dans lequel il s'exécute. Pour en savoir plus, consultez la description de l'objet de configuration.

Pour l'implémentation du lanceur de test, vous devez implémenter IConfigurationReceiver pour recevoir l'objet IConfiguration.

Exécuteur de test flexible

Les outils d'exécution de tests peuvent fournir un moyen flexible d'exécuter leurs tests s'ils disposent d'un contrôle précis sur eux. Par exemple, un outil d'exécution de tests JUnit peut exécuter individuellement chaque test unitaire.

Cela permet au harnais et à l'infrastructure plus importants d'exploiter ce contrôle précis et aux utilisateurs d'exécuter partiellement le lanceur de test via le filtrage.

La prise en charge du filtrage est décrite dans l'interface ITestFilterReceiver, qui permet de recevoir des ensembles de filtres include et exclude pour les tests qui doivent ou ne doivent pas s'exécuter.

Notre convention est qu'un test est exécuté SI ET SEULEMENT s'il correspond à un ou plusieurs des filtres d'inclusion ET qu'il ne correspond à aucun des filtres d'exclusion. Si aucun filtre d'inclusion n'est fourni, tous les tests doivent être exécutés tant qu'ils ne correspondent à aucun des filtres d'exclusion.