Ce tutoriel vous explique comment créer un "Hello World" Fédération du commerce (Tradefed ou TF) et d'une introduction pratique à TF d'infrastructure. À partir d'un environnement de développement, vous allez créer la configuration et ajouter des fonctionnalités.
Le tutoriel présente le processus de développement de tests sous la forme d'une série d'exercices, composées chacune de plusieurs étapes, qui montrent comment créer pour affiner votre configuration. Tous les exemples de code dont vous avez besoin pour effectuer le test est fournie, et le titre de chaque exercice est annoté lettre décrivant les rôles impliqués dans cette étape:
- D pour "Développeur"
- I (intégrateur)
- R pour Test Runner
Une fois le tutoriel terminé, vous disposerez d'une configuration TF opérationnelle et comprendre de nombreux concepts importants du framework TF.
Configurer une fédération commerciale
Pour savoir comment configurer l'environnement de développement TF, consultez Machine Configuration. Dans la suite de ce tutoriel, nous partons du principe que vous disposez d'un shell ouvert qui a été initialisé dans l'environnement TF.
Par souci de simplicité, ce tutoriel explique comment ajouter une configuration et ses à la bibliothèque principale du framework TF. Cela peut s'étendre au développement en dehors de l'arborescence source en compilant le fichier JAR échangé, puis en compilant vos modules par rapport à ce fichier JAR.
Créer une classe de test (D)
Créons un test Hello World qui transfère simplement un message vers stdout. A le test tradefed implémente généralement IRemoteTest de commande. Voici une implémentation pour HelloWorldTest:
package com.android.tradefed.example; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.invoker.TestInformation; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.result.ITestInvocationListener; import com.android.tradefed.testtype.IRemoteTest; public class HelloWorldTest implements IRemoteTest { @Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World!"); } }
Enregistrez cet exemple de code dans
<tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
puis recompilez votre échange depuis votre shell:
m -jN
Notez que CLog.i
dans l'exemple ci-dessus est utilisé pour diriger la sortie vers la console. Plus
les informations relatives à la journalisation dans la fédération du commerce sont décrites dans la section Journalisation (D, I, R).
Si la compilation échoue, consultez Machine Configuration pour vous assurer de ne manquer aucune étape.
Créer une configuration (I)
Les tests de la fédération du commerce sont rendus exécutables en créant un Configuration : un fichier XML indiquant les données échangées (ou tests) à exécuter, ainsi que les autres modules à exécuter et dans quels cas commande.
Créons une configuration pour notre HelloWorldTest (notez que la classe complète de la classe HelloWorldTest):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
Enregistrez ces données dans un fichier helloworld.xml
sur votre disque local
système de fichiers (par exemple, /tmp/helloworld.xml
). TF analyse le paramètre
Fichier XML de configuration (ou config), chargez la classe spécifiée en utilisant
la réflexion, l'instancier, la caster en IRemoteTest
et l'appeler
run
.
Exécuter la configuration (R)
À partir de votre shell, lancez la console tradefed:
tradefed.sh
Assurez-vous qu'un appareil est connecté à la machine hôte et qu'il est visible pour les échanges:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Les configurations peuvent être exécutées à l'aide de l'run <config>
console. Conseil :
tf> run /tmp/helloworld.xml 05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
Le message "Hello, TF World!" doit s'afficher. sur le terminal.
Vous pouvez vérifier qu'une commande est bien exécutée en utilisant list invocations
ou
l i
dans l'invite de la console, et rien ne devrait s'afficher. Si les commandes sont actuellement
en cours d'exécution, elles s'affichent comme suit:
tf >l i Command Id Exec Time Device State 10 0m:00 [876X00GNG] running stub on build(s) 'BuildInfo{bid=0, target=stub, serial=876X00GNG}'
Ajouter la configuration au chemin de classe (D, I, R)
Pour faciliter le déploiement, vous pouvez aussi regrouper les configurations dans des fichiers JAR eux-mêmes. Tradefed reconnaît automatiquement toutes les configurations placées dans config sur le chemin de classe.
Par exemple, déplacez le fichier helloworld.xml
dans le fichier tradefed
bibliothèque principale
(<tree>/tools/tradefederation/core/res/config/example/helloworld.xml
).
Reconstruisez la console échangée, redémarrez la console, puis demandez à tradefed d'afficher
liste des configurations à partir du classpath:
tf> list configs […] example/helloworld: Runs the hello world test
Vous pouvez maintenant exécuter la configuration helloworld à l'aide de la commande suivante:
tf> run example/helloworld 05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
Interagir avec un appareil (D, R)
Pour l'instant, HelloWorldTest ne fait rien d'intéressant. Tradefed's est d'effectuer des tests avec des appareils Android. à l'épreuve.
Les tests peuvent obtenir une référence à un appareil Android à l'aide de TestInformation
, fourni
par le framework lorsque la méthode IRemoteTest#run
est appelée.
Modifions à présent le message d'impression HelloWorldTest pour afficher le numéro de série l'appareil:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
À présent, recompilez votre échange et vérifiez la liste des appareils:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Notez le numéro de série indiqué comme Disponible. qui est l'appareil qui doit être alloué à HelloWorld:
tf> run example/helloworld 05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548
Le nouveau message d'impression indiquant le numéro de série du appareil.
Envoyer les résultats du test (D)
IRemoteTest
signale les résultats en appelant des méthodes sur le
Écouteur d'appels d'objets
fournie à la méthode #run
. Le framework TF lui-même
responsable de la création de rapports sur les débuts (via
ITestInvocationListener#invocationStarted)
et à la fin (via
ITestInvocationListener#invocationEnded)
de chaque appel.
Une exécution de test est une collection logique de tests. Pour générer des rapports
sur les résultats des tests,
IRemoteTest
permet de signaler le début de l'exécution d'un test.
le début et la fin de chaque test, et la fin du test.
Voici à quoi pourrait ressembler l'implémentation de HelloWorldTest avec un seul échec du résultat du test.
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); TestDescription testId = new TestDescription("com.example.TestClassName", "sampleTest"); listener.testRunStarted("helloworldrun", 1); listener.testStarted(testId); listener.testFailed(testId, "oh noes, test failed"); listener.testEnded(testId, Collections.emptyMap()); listener.testRunEnded(0, Collections.emptyMap()); }
TF inclut plusieurs implémentations IRemoteTest
que vous pouvez réutiliser
au lieu d'écrire les vôtres
à partir de zéro. Par exemple :
Test d'instrumentation
peut exécuter les tests d'une application Android à distance sur un appareil Android, analyser le
et les transmettre au ITestInvocationListener
).
Pour en savoir plus, consultez
Test
Types.
Stocker les résultats des tests (I)
L'implémentation de l'écouteur de test par défaut pour une configuration TF est la suivante : TextResultReporter, qui vide les résultats d'un appel vers stdout. Par exemple, exécutez la commande Configuration HelloWorldTest de la section précédente:
./tradefed.sh
tf> run example/helloworld 04-29 18:25:55 I/TestInvocation: Invocation was started with cmd: /tmp/helloworld.xml 04-29 18:25:55 I/TestInvocation: Starting invocation for 'stub' with '[ BuildInfo{bid=0, target=stub, serial=876X00GNG} on device '876X00GNG'] 04-29 18:25:55 I/HelloWorldTest: Hello, TF World! I have device 876X00GNG 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Running helloworldrun: 1 tests 04-29 18:25:55 W/InvocationToJUnitResultForwarder: Test com.example.TestClassName#sampleTest failed with stack: oh noes, test failed 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Run ended in 0 ms
Pour stocker les résultats d'une invocation ailleurs, par exemple dans un fichier, spécifiez un
une implémentation personnalisée de ITestInvocationListener
à l'aide de
Balise result_reporter
dans votre configuration.
TF inclut également
XmlResultReporter
"Listener" qui écrit les résultats des tests dans un fichier XML dans un format semblable à celui-ci
utilisé par le rédacteur XML ant JUnit. Pour spécifier le paramètre "result_reporter" dans
modifier la configuration, modifiez …/res/config/example/helloworld.xml
configuration:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
À présent, recréez les données échangées et exécutez à nouveau l'exemple Hello World:
tf> run example/helloworld 05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548 05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt 05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_2991649128735283633/host_log_6307746032218561704.txt 05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /tmp/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
Notez le message de journal indiquant qu'un fichier XML a été généré : la généré doit se présenter comme suit:
<?xml version='1.0' encoding='UTF-8' ?> <testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"> <properties /> <testcase name="sampleTest" classname="com.example.TestClassName" time="0"> <failure>oh noes, test failed </failure> </testcase> </testsuite>
Vous pouvez également écrire vos propres écouteurs d'appel personnalisés. Ils vous n'avez pas besoin d'implémenter Écouteur d'appels d'API ITestInvocation de commande.
Tradefed accepte plusieurs écouteurs d'appel, ce qui vous permet d'envoyer les résultats des tests
vers plusieurs destinations indépendantes. Pour ce faire, il vous suffit de spécifier plusieurs
Balises <result_reporter>
dans votre configuration.
Installations d'exploitation forestière (D, I, R)
Parmi les installations de journalisation de TensorFlow, on peut citer:
- Capturer les journaux de l'appareil (également appelé Logcat de l'appareil)
- Enregistrer des journaux à partir du framework de la fédération commerciale s'exécutant sur la machine hôte (également appelé "journal de l'hôte")
Le framework TF capture automatiquement le fichier logcat à partir de l'appareil alloué
et l'envoie à l'écouteur d'appel pour traitement.
XmlResultReporter
enregistre ensuite le Logcat de l'appareil capturé en tant que fichier.
Les journaux de l'hôte TF sont signalés à l'aide du
Wrapper de journalisation
pour la classe Log ddmlib. Convertissons
précédent appel System.out.println
dans HelloWorldTest à une
Appel CLog
:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
gère directement l'interpolation de chaîne, comme pour
String.format
Lorsque vous recompilez et réexécutez TF, vous devez voir
Message de journal sur stdout:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
Par défaut, les données échangées
sortie du journal de l'hôte
des messages à stdout. TF inclut également une implémentation de journal qui écrit
messages dans un fichier:
FileLogger
Pour ajouter la journalisation des fichiers, ajoutez une balise logger
à la configuration, en spécifiant le
Nom complet de classe FileLogger
:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> <logger class="com.android.tradefed.log.FileLogger" /> </configuration>
Maintenant, recompilez et exécutez à nouveau l'exemple helloworld:
tf >run example/helloworld … 05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt 05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt …
Le message de journal indique le chemin du journal de l'hôte qui, une fois affiché, doit contenir votre message de journal HelloWorldTest:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
Exemple de résultat :
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
Options de traitement (D, I, R)
Objets chargés à partir d'une configuration TF (également appelés objets de configuration)
peut également recevoir des données à partir d'arguments de ligne de commande à l'aide du
Annotation @Option
.
Pour participer, une classe d'objet Configuration applique l'@Option
à un champ de membre et lui attribue un nom unique. Cela permet
valeur du champ membre à renseigner via une option de ligne de commande (et aussi
ajoute automatiquement cette option au système d'aide à la configuration).
Remarque:Tous les types de champs ne sont pas acceptés. Pour une des types pris en charge, reportez-vous à OptionSetter :
Ajoutons un @Option
à HelloWorldTest:
@Option(name="my_option", shortName='m', description="this is the option's help text", // always display this option in the default help text importance=Importance.ALWAYS) private String mMyOption = "thisisthedefault";
Ensuite, ajoutons un message de journal pour afficher la valeur de l'option dans HelloWorldTest afin de vérifier qu'il a bien été reçu:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
Enfin, recompilez TF et exécutez helloworld. vous devriez voir un message de journal indiquant
Valeur par défaut de my_option
:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
Transmettre des valeurs à partir de la ligne de commande
Transmettez une valeur pour my_option
. vous devriez voir
my_option
renseigné avec cette valeur:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
Les configurations TF incluent également un système d'aide qui affiche automatiquement
Texte d'aide pour les champs @Option
. Essayez maintenant. Vous devriez voir
texte d'aide pour my_option
:
tf> run example/helloworld --help Printing help for only the important options. To see help for all options, use the --help-all flag cmd_options options: --[no-]help display the help text for the most important/critical options. Default: false. --[no-]help-all display the full help text for all options. Default: false. --[no-]loop keep running continuously. Default: false. test options: -m, --my_option this is the option's help text Default: thisisthedefault. 'file' logger options: --log-level-display the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
Notez le message "n'imprimer que les options importantes". Pour réduire
une aide encombrante, TF utilise l'attribut Option#importance
pour
déterminer si un texte d'aide de champ @Option
spécifique doit s'afficher
--help
est spécifié. --help-all
affiche toujours de l'aide pour
tous les champs @Option
, quelle que soit leur importance. Pour en savoir plus, consultez
Option.Importance :
Transmettre des valeurs à partir d'une configuration
Vous pouvez également spécifier une valeur "Option" dans la configuration en ajoutant un
Élément <option name="" value="">
. Testez-le avec
helloworld.xml
:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
La reconstruction et l'exécution de helloworld devraient maintenant générer le résultat suivant:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
L'aide à la configuration devrait également être mise à jour pour indiquer la valeur par défaut de
my_option
:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
D'autres objets de configuration inclus dans la configuration helloworld, tels que
FileLogger
, acceptez également les options. L'option
--log-level-display
est intéressant, car il filtre les journaux qui
apparaissent sur stdout. Plus tôt dans ce tutoriel, vous avez peut-être remarqué le message
Monde ! J'ai un appareil..." le message de journal a cessé de s'afficher sur stdout
est passé à FileLogger
. Vous pouvez augmenter la verbosité
vous connecter à stdout en transmettant l'argument --log-level-display
;
Essayez dès maintenant. Le message "I have device" (J'ai un appareil) devrait s'afficher. le message de journal réapparaît le stdout, en plus d'être connecté à un fichier:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
C'est tout !
Pour rappel, si vous êtes bloqué(e) sur quelque chose, Commerce Le code source de la fédération contient de nombreuses informations utiles, qui ne sont pas exposées dans la documentation. Si le problème persiste, posez la question sur plate-forme-android le groupe Google, avec "Trade Fédération" dans l'objet du message.