Écrire un testeur Tradefed

Cette page décrit comment écrire un nouveau programme d'exécution de test dans Tradefed.

Arrière-plan

Si vous êtes curieux de connaître la place des testeurs dans l'architecture Tradefed, voir Structure d'un Test Runner .

Ce n’est pas une condition préalable à l’écriture d’un nouveau programme d’exécution de tests ; les exécuteurs de tests peuvent être écrits de manière isolée.

Bar minimum : implémenter l’interface

Le strict minimum pour être qualifié de lanceur de tests Tradefed est d'implémenter l' interface IRemoteTest et plus spécifiquement la méthode run(TestInformation testInfo, ITestInvocationListener listener) .

Cette méthode est celle invoquée par le harnais lors de l'utilisation du lanceur de tests, similaire à un Java Runnable.

Chaque partie de cette méthode est considérée comme faisant partie de l’exécution du programme d’exécution du test.

Rapporter les résultats du programme d'exécution du test

La méthode run dans l'interface de base donne accès à un objet écouteur de type ITestInvocationListener . Cet objet est la clé pour rapporter les résultats structurés du lanceur de test au harnais.

En rapportant des résultats structurés, un exécuteur de test possède les propriétés suivantes :

  • Signalez une liste appropriée de tous les tests exécutés, combien de temps ils ont pris et s'ils ont réussi, échoué ou dans d'autres états.
  • Signalez les métriques associées aux tests, le cas échéant, par exemple les métriques de temps d'installation.
  • Intégrez la plupart des outils d'infrastructure, par exemple l'affichage des résultats et des métriques, etc.
  • Généralement plus facile à déboguer car il existe une trace plus granulaire de l’exécution.

Cela dit, la communication de résultats structurés est facultative ; un exécuteur de test peut simplement vouloir évaluer l'état de l'exécution entière comme RÉUSSI ou É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 : notifie le début d'un groupe de scénarios de test liés entre eux.
    • testStarted : notifie le début du démarrage d'un scénario de test.
    • testFailed/testIgnored : Notifier le changement d'état du scénario de test en cours. Un cas de test sans aucun changement d’état est considéré comme réussi.
    • testEnded : notifie la fin du scénario de test.
  • testRunFailed : notifie que l'état global de l'exécution du groupe de scénarios de test est un échec. Une exécution de test peut être une réussite ou un échec indépendamment des résultats des scénarios de test , en fonction de ce à quoi l'exécution s'attendait. Par exemple, un binaire exécutant plusieurs scénarios de test pourrait signaler tous les scénarios de test réussis mais avec un code de sortie d'erreur (pour quelque raison que ce soit : fuite de fichiers, etc.).
  • testRunEnded : notifie la fin du groupe de cas de test.

Le maintien et la garantie du bon ordre des rappels relèvent de la responsabilité de l'implémenteur du programme d'exécution de test, par exemple en s'assurant que testRunEnded est 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 avoir lieu sans aucun scénario de test.

Vous remarquerez peut-être que cette structure d'événements est inspirée de la structure typique de JUnit . C'est volontairement pour garder les choses proches de quelque chose de basique que les développeurs ont généralement des connaissances.

Rapporter les journaux du programme d'exécution du test

Si vous écrivez votre propre classe de test ou exécuteur Tradefed, vous implémenterez IRemoteTest et obtiendrez un ITestInvocationListener via la méthode run() . Cet écouteur peut être utilisé pour enregistrer les 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 pas de ressources particulières, par exemple des tests unitaires Java.

Les rédacteurs de tests qui souhaitent passer à l’étape suivante du test des appareils auront besoin des interfaces suivantes :

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

Les testeurs 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 le périphérique testé qui sera ciblé lors de l'exécution.

Tester avec plusieurs appareils

Tradefed prend en charge l'exécution de tests sur plusieurs appareils en même temps. Ceci est utile lors du test de composants qui nécessitent une interaction externe, comme l’association d’un téléphone et d’une montre.

Afin d'écrire un programme d'exécution de tests pouvant utiliser plusieurs appareils, vous devrez implémenter le IMultiDeviceTest , qui permettra de recevoir une carte de ITestDevice vers IBuildInfo contenant la liste complète des représentations de périphériques et leurs informations de construction associées.

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

Tests conscients de leurs configurations

Certaines implémentations de testeurs peuvent avoir besoin d'informations sur la configuration globale pour fonctionner correctement, par exemple des métadonnées sur l'invocation, ou sur le target_preparer exécuté auparavant, etc.

Pour y parvenir, un exécuteur de test peut accéder à l'objet IConfiguration dont il fait partie et dans lequel il est exécuté. Voir la description de l'objet de configuration pour plus de détails.

Pour l’implémentation du lanceur de tests, vous devrez implémenter IConfigurationReceiver pour recevoir l’objet IConfiguration .

Testeur flexible

Les exécuteurs de tests peuvent fournir un moyen flexible d'exécuter leurs tests s'ils en ont un contrôle granulaire, par exemple un exécuteur de tests JUnit peut exécuter individuellement chaque test unitaire.

Cela permet au harnais et à l'infrastructure plus vastes d'exploiter ce contrôle précis et aux utilisateurs d'exécuter partiellement le lanceur de tests 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 non s'exécuter.

Notre convention est qu'un test sera exécuté IFF s'il correspond à un ou plusieurs des filtres d'inclusion ET 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.