Écrire un testeur Tradefed

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

Fond

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

Ce n'est pas une condition préalable à l'écriture d'un nouveau testeur ; les exécuteurs de test peuvent être écrits isolément.

Le strict minimum : Implémenter l'interface

Le strict minimum pour se qualifier en tant que testeur Tradefed est d'implémenter l' interface IRemoteTest et plus précisément la run(TestInformation testInfo, ITestInvocationListener listener) .

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

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

Rapporter les résultats du testeur

La méthode run de 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 testeur au harnais.

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

  • Rapportez une liste appropriée de tous les tests qui ont été exécutés, combien de temps ils ont pris et s'ils ont individuellement réussi, échoué ou d'autres états.
  • Indiquez les métriques associées aux tests, le cas échéant, par exemple les métriques de temps d'installation.
  • S'adapte à la plupart des outils d'infrastructure, par exemple afficher les résultats et les métriques, etc.
  • Généralement plus facile à déboguer car il y a 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'ensemble de l'exécution comme RÉUSSI ou ÉCHEC sans aucun détail sur l'exécution réelle.

REMARQUE : il est plus difficile de mettre en œuvre un coureur qui suit la séquence des événements, mais nous vous recommandons de le faire compte tenu des avantages énumérés ci-dessus.

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

  • testRunStarted : Notifier le début d'un groupe de cas de test liés entre eux.
    • testStarted : notifie le début d'un scénario de test qui démarre.
    • testFailed/testIgnored : Notifier le changement d'état du cas de test en cours. Un cas de test sans aucun changement d'état est considéré comme réussi.
    • testEnded : Notifier la fin du cas de test.
  • testRunFailed : notifie que l'état global de l'exécution du groupe de cas de test est un échec. Une exécution de test peut être une réussite 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 cas de test pourrait signaler tous les cas de test réussis mais avec un code de sortie d'erreur (pour n'importe quelle raison : fuite de fichiers, etc.).
  • testRunEnded : notifier 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 testeur, par exemple en s'assurant que testRunEnded est appelé en cas d'exception à l'aide d'une clause finally .

Les rappels de cas de test ( testStarted , testEnded , etc.) sont facultatifs. Une exécution de test peut se produire 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 exprès pour garder les choses proches de quelque chose de basique que les développeurs ont généralement des connaissances.

Rapporter les journaux de l'exécuteur de test

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 enregistrer 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 qui sont isolés et ne nécessitent pas de ressources particulières, par exemple des tests unitaires Java.

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

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

Les lanceurs de test sont généralement intéressés par 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 sous 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 lorsque vous testez des composants qui nécessitent une interaction externe, comme un téléphone et un couplage de montre.

Afin d'écrire un lanceur de test pouvant utiliser plusieurs appareils, vous devrez implémenter le IMultiDeviceTest , qui permettra de recevoir une carte de ITestDevice à IBuildInfo contenant la liste complète des représentations d'appareils 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

REMARQUE : Il ne s'agit pas d'un cas d'utilisation très courant. Il est documenté par souci d'exhaustivité, mais vous n'en aurez généralement pas besoin.

Certaines implémentations de test runner peuvent avoir besoin d'informations sur la configuration globale pour fonctionner correctement, par exemple des métadonnées sur l'invocation, ou quel target_preparer a été exécuté avant, etc.

Pour ce faire, un testeur peut accéder à l'objet IConfiguration 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 de test runner, vous devrez implémenter IConfigurationReceiver pour recevoir l'objet IConfiguration .

Coureur de test flexible

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

Cela permet au plus grand harnais et à l'infrastructure de tirer parti de ce contrôle précis et aux utilisateurs d'exécuter partiellement le testeur via le filtrage .

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

Notre convention est qu'un test sera exécuté IFF 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.

REMARQUE : Nous encourageons les exécuteurs de test à écrire d'une manière qui prend en charge ce filtrage car il offre une énorme valeur ajoutée dans l'infrastructure plus large. Mais nous comprenons que dans certains cas, il n'est pas possible de le faire.