Questo tutorial illustra la creazione di un "Hello World" Federazione commerciale (Tradefed or TF) e offre un'introduzione pratica a TF il modello di machine learning. Partendo da un ambiente di sviluppo, creerai una semplice configurazione e aggiungere funzionalità.
Il tutorial presenta il processo di sviluppo del test come una serie di esercizi, ciascuno costituito da diversi passaggi, che mostrano come creare e implementare per perfezionare la configurazione. Tutto il codice campione necessario per completare il test configurazione iniziale e il titolo di ogni esercizio è annotato con lettera che descrive i ruoli coinvolti in questa fase:
- D per sviluppatore
- I per integratore
- R per Test Runner
Dopo aver completato il tutorial, avrai una configurazione TF funzionante e di comprendere molti concetti importanti nel framework di TF.
Configura Trade Federation
Per maggiori dettagli sulla configurazione dell'ambiente di sviluppo TF, vedi Macchina Configurazione. Il resto del tutorial presuppone che tu abbia una shell aperta inizializzato nell'ambiente TF.
Per semplicità, questo tutorial illustra l'aggiunta di una configurazione e delle relative alla libreria di base del framework TF. Questo può essere esteso allo sviluppo moduli esterni all'albero di origine mediante la compilazione del JAR traslato, quindi la compilazione dei moduli rispetto al JAR.
Crea una classe di prova (D)
Creiamo un test Hello World che si limita a eseguire il dump di un messaggio su stdout. R tradefed test implementa generalmente Testa remota a riga di comando. Di seguito è riportata un'implementazione per 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!"); } }
Salva questo codice campione in
<tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
e ricrearla traslata dalla tua shell:
m -jN
Tieni presente che CLog.i
nell'esempio precedente viene utilizzato per indirizzare l'output alla console. Altro
le informazioni sul logging nella Federazione commerciale sono descritte in Logging (D, I, R).
Se la creazione non riesce, consulta una Macchina per assicurarti di non perdere un passaggio.
Crea una configurazione (I)
I test della Trade Federation vengono resi eseguibili creando un Configuration, un file XML che fornisce istruzioni su quale test (o test) da eseguire, nonché quali altri moduli eseguire e in quale ordine.
Creiamo una nuova configurazione per il nostro HelloWorldTest (vedi il corso completo) nome di HelloWorldTest):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
Salva questi dati in un file helloworld.xml
in qualsiasi punto della tua rete locale
file system (ad es. /tmp/helloworld.xml
). TF analizzerà
Il file XML di configurazione (noto anche come config), carica la classe specificata utilizzando
riflessione, creare un'istanza, trasmetterla a IRemoteTest
e richiamare il suo
run
.
Esegui la configurazione (R)
Avvia la console trasferita dalla tua shell:
tradefed.sh
Assicurati che un dispositivo sia connesso alla macchina host e sia visibile alla trasferta:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Le configurazioni possono essere eseguite utilizzando run <config>
nella console Google Cloud. Prova:
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!
Dovresti vedere il messaggio "Hello, TF World!". l'output sul terminale.
Puoi verificare che un comando sia stato eseguito utilizzando list invocations
oppure
l i
nel messaggio della console e non dovrebbe essere stampato nulla. Se al momento i comandi sono
in esecuzione, vengono visualizzati come segue:
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}'
Aggiungi la configurazione al classpath (D, I, R)
Per maggiore praticità, puoi anche raggruppare le configurazioni I JAR stessi. Tradefed riconosce automaticamente tutte le configurazioni inserite config sulla classe.
Per spiegarci meglio, sposta il file helloworld.xml
nel file convertito
libreria di base
(<tree>/tools/tradefederation/core/res/config/example/helloworld.xml
).
Ricostruisci tradef tramite, riavvia la console tradefed, quindi chiedi tradefed per visualizzare il
elenco di configurazioni da classpath:
tf> list configs […] example/helloworld: Runs the hello world test
Ora puoi eseguire la configurazione di helloworld utilizzando:
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!
Interagire con un dispositivo (D, R)
Al momento, il nostro HelloWorldTest non ha dato risultati interessanti. Tradefed è l'esecuzione di test con dispositivi Android, quindi aggiungiamo un dispositivo Android al test.
I test possono ottenere un riferimento a un dispositivo Android utilizzando TestInformation
, fornito
dal framework quando viene chiamato il metodo IRemoteTest#run
.
Modifichiamo il messaggio di stampa HelloWorldTest per visualizzare il numero di serie il dispositivo:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
Ora puoi ricreare la trasferta e controllare l'elenco dei dispositivi:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Prendi nota del numero di serie indicato come Available. ovvero il dispositivo che deve essere allocato a 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
Dovresti vedere il nuovo messaggio di stampa che mostra il numero di serie del dispositivo.
Invia risultati test (D)
IRemoteTest
restituisce i risultati richiamando metodi sul
ITestInvocationListener
fornita al metodo #run
. Il framework TF stesso
responsabile di segnalare l'inizio (tramite
ITestInvocationListener#invocationStarted)
e alla fine (tramite
ITestInvocationListener#invocationEnded)
di ogni chiamata.
Un'esecuzione di test è una raccolta logica di test. Per segnalare i risultati del test,
IRemoteTest
è responsabile di segnalare l'inizio di un'esecuzione di test,
l'inizio e la fine di ogni test e la fine dell'esecuzione del test.
Ecco come potrebbe presentarsi l'implementazione HelloWorldTest con una singola risultato del test non superato.
@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 include diverse implementazioni IRemoteTest
che puoi riutilizzare
anziché scriverne uno tutto tuo da zero. Ad esempio:
Test di strumentazione
eseguire i test di un'applicazione Android da remoto su un dispositivo Android, analizzare
risultati e inoltrali al team ITestInvocationListener
).
Per maggiori dettagli, vedi
Prova
Tipi.
Archivia i risultati del test (I)
L'implementazione predefinita del listener di test per una configurazione TF è TextResultReporter che scarica i risultati di una chiamata a stdout. Per illustrare il concetto, esegui il comando Configurazione di HelloWorldTest della sezione precedente:
./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
Per archiviare i risultati di una chiamata altrove, ad esempio in un file, specifica
implementazione personalizzata di ITestInvocationListener
utilizzando
result_reporter
nella tua configurazione.
TF include anche
XmlResultReporter
listener, che scrive i risultati del test in un file XML in un formato simile a quello
utilizzato dal writer XML JUnit ant. Per specificare result_reporter nel
modifica la configurazione di …/res/config/example/helloworld.xml
configurazione:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
Ora ricrea la trasferta ed esegui di nuovo l'esempio di 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
Osserva il messaggio di log che indica che è stato generato un file XML. il generato dovrebbe avere il seguente aspetto:
<?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>
Puoi anche scrivere listener di chiamata personalizzati, semplicemente devi implementare ITestInvocationListener a riga di comando.
Tradefed supporta più listener di chiamate, quindi puoi inviare i risultati del test
verso più destinazioni indipendenti. Per farlo, è sufficiente specificare più
<result_reporter>
tag nella configurazione.
Impianti di lavorazione forestale (D, I, R)
Le strutture di registrazione di TF offrono la possibilità di:
- Acquisire i log dal dispositivo (noto anche come logcat del dispositivo)
- Registra i log dal framework della Trade Federation in esecuzione sul computer host (noto anche come log host)
Il framework TF acquisisce automaticamente il logcat dal dispositivo allocato
e la invia al listener di chiamate per l'elaborazione.
XmlResultReporter
salva quindi il logcat del dispositivo acquisito come file.
I log host TF vengono segnalati utilizzando
Wrapper CLog
per la classe ddmlib Log. Convertiamo
precedente chiamata System.out.println
in HelloWorldTest a un
Chiamata CLog
:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
gestisce direttamente l'interpolazione di stringhe, come
String.format
. Quando ricrei ed esegui di nuovo TF, dovresti vedere
messaggio di log su stdout:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
Per impostazione predefinita,
log host di output
a stdout. TF include anche un'implementazione di log che scrive
messaggi in un file:
FileLogger.
Per aggiungere il logging dei file, aggiungi un tag logger
alla configurazione, specificando il
nome completo della 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>
Ora ricrea ed esegui di nuovo l'esempio di 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 …
Il messaggio di log indica il percorso del log dell'host che, quando visualizzato, deve contenere il messaggio di log HelloWorldTest:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
Output di esempio:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
Opzioni di gestione (D, I, R)
Oggetti caricati da una configurazione TF (noti anche come oggetti di configurazione)
può anche ricevere dati da argomenti della riga di comando utilizzando
annotazione @Option
.
Per partecipare, una classe di oggetti Configurazione applica @Option
a un campo membro e gli assegna un nome univoco. Ciò consente
il valore del campo membro da compilare tramite un'opzione della riga di comando (e anche
l'opzione viene aggiunta automaticamente al sistema di assistenza per la configurazione).
Nota: non tutti i tipi di campo sono supportati. Per un la descrizione dei tipi supportati, consulta OptionSetter.
Aggiungiamo @Option
a 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";
Quindi, aggiungiamo un messaggio di log per visualizzare il valore dell'opzione HelloWorldTest per consentirci di dimostrare che è stato ricevuto correttamente:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
Infine, ricrea TF ed esegui helloworld; dovresti vedere un messaggio di log con
Valore predefinito my_option
:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
Trasmettere valori dalla riga di comando
Trasmetti un valore per my_option
; dovresti vedere
my_option
compilato con questo valore:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
Le configurazioni TF includono anche un sistema di guida, che visualizza automaticamente
testo della guida per i campi @Option
. Prova subito; dovresti vedere lo
testo della guida per 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.
Annota il messaggio sulla "stampa solo delle opzioni importanti". Per ridurre
aiuta a creare confusione, TF usa l'attributo Option#importance
per
determinare se mostrare un determinato testo della guida del campo @Option
quando
--help
è specificato. --help-all
mostra sempre la guida per
tutti i @Option
campi, indipendentemente dall'importanza. Per maggiori dettagli, vedi
Option.Importance (Opzione.Importanza).
Trasmettere valori da una configurazione
Puoi anche specificare un valore di opzione all'interno della configurazione aggiungendo
Elemento <option name="" value="">
. Esegui un test utilizzando
helloworld.xml
:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
La ricreazione ed esecuzione di helloworld dovrebbe ora produrre questo output:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
Anche la guida di configurazione dovrebbe aggiornarsi per indicare il valore predefinito
my_option
:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
Altri oggetti di configurazione inclusi nella configurazione di helloworld, ad esempio
FileLogger
, accetta anche opzioni. L'opzione
--log-level-display
è interessante perché filtra i log che
vengono visualizzati su stdout. In precedenza, nel tutorial, potresti aver notato la
Mondo! Ho il dispositivo..." il messaggio di log non viene più visualizzato su stdout dopo che
è passata all'utilizzo di FileLogger
. Puoi aumentare il livello di dettaglio
logging a stdout passando l'argomento --log-level-display
.
Prova ora; dovresti vedere il messaggio "Ho il dispositivo" il messaggio di log riapparirà stdout, oltre a essere registrato in un file:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
È tutto!
Ricorda che, se sei bloccato su qualcosa, Commercio Il codice sorgente della federazione contiene molte informazioni utili che non sono esposte nei la documentazione. Se il problema persiste, prova a chiedere nella piattaforma-android Gruppo Google, con "Trade Federation" nell'oggetto del messaggio.