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.