Cette page explique comment écrire un nouveau test runner dans Tradefed.
Arrière-plan
Si vous souhaitez en savoir plus sur la place des exécuteurs de tests dans l'architecture Tradefed, consultez Structure d'un exécuteur de tests.
Il ne s'agit pas d'une condition préalable à l'écriture d'un nouveau test runner. Les test runners peuvent être écrits de manière isolée.
Le strict minimum : implémenter l'interface
Pour être considéré comme un test runner Tradefed, il faut au minimum 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 lors de l'utilisation du test runner, comme un Runnable Java.
Chaque partie de cette méthode est considérée comme faisant partie de l'exécution du test runner.
Rapporter les résultats du test runner
La méthode run
de l'interface de base donne accès à un objet d'écouteur de type ITestInvocationListener
. Cet objet est la clé pour signaler les résultats structurés du test runner au harnais.
En signalant des résultats structurés, un exécuteur de tests présente les propriétés suivantes :
- Fournissez une liste appropriée de tous les tests exécutés, de leur durée et de leur état (réussite, échec ou autre).
- Si applicable, signalez les métriques associées aux tests, par exemple les métriques sur le temps d'installation.
- S'intégrer à la plupart des outils d'infrastructure, par exemple pour afficher les résultats et les métriques, etc.
- Le débogage est généralement plus facile, car la trace de l'exécution est plus précise.
Cela dit, il n'est pas obligatoire de générer des rapports sur les résultats structurés. Un test runner peut simplement vouloir évaluer l'état de l'ensemble de l'exécution comme RÉUSSI ou ÉCHOUÉ, 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 : notifier le début d'un groupe de scénarios de test associés.
- testStarted : notifier le début d'un cas de test.
- testFailed/testIgnored : notifier 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 : notifier 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 réussie ou échouer indépendamment des résultats des scénarios de test, selon ce qui était attendu de l'exécution. 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 d'erreur de sortie (pour diverses raisons : fichiers divulgués, etc.).
- testRunEnded : notifier la fin du groupe de scénarios de test.
Il incombe à l'implémenteur du programme d'exécution des tests de maintenir et de garantir l'ordre approprié des rappels, 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 avoir lieu sans aucun scénario de test.
Vous remarquerez peut-être que cette structure d'événements s'inspire de la structure JUnit typique. C'est volontaire, afin de rester proche d'un élément de base que les développeurs connaissent généralement.
Signaler les journaux du test runner
Si vous écrivez votre propre classe ou runner de test Tradefed, vous implémenterez IRemoteTest et obtiendrez un ITestInvocationListener
via la méthode run()
. Ce listener peut être utilisé pour enregistrer des fichiers journaux 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 de test de l'appareil 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 compilation, qui contient toutes les informations et tous les artefacts liés à la configuration du test.
Les responsables des tests 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 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 pour tester des composants qui nécessitent une interaction externe, comme l'association d'un téléphone et d'une montre.
Pour écrire un test runner 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 des informations de compilation associées.
Le setter de l'interface sera toujours appelé avant la méthode run
. Vous pouvez donc supposer que la structure sera disponible lorsque run
sera appelé.
Tests conscients de leur configuration
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 sur le target_preparer
qui s'est exécuté avant, etc.
Pour ce faire, un exécuteur de test peut accéder à l'objet IConfiguration
dont il fait partie et dans lequel il est exécuté. Pour en savoir plus, consultez la description de l'objet de configuration.
Pour l'implémentation du test runner, vous devrez implémenter IConfigurationReceiver pour recevoir l'objet IConfiguration
.
Exécuteur de tests flexible
Les lanceurs 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 lanceur de tests JUnit peut exécuter individuellement chaque test unitaire.
Cela permet à l'infrastructure et au harnais plus larges de tirer parti de ce contrôle précis, et aux utilisateurs d'exécuter partiellement le test runner via le filtrage.
La compatibilité avec le 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 être exécutés.
Notre convention est qu'un test sera exécuté SI ET SEULEMENT SI il correspond à un ou plusieurs filtres d'inclusion ET ne correspond à aucun filtre d'exclusion. Si aucun filtre d'inclusion n'est spécifié, tous les tests doivent être exécutés, à condition qu'ils ne correspondent à aucun des filtres d'exclusion.