Beispiel für einen End-to-End-TF-Test

In dieser Anleitung erfahren Sie, wie Sie ein „Hello World“-Modell erstellen Handelsföderation Testkonfiguration (Tradefed oder TF) und gibt Ihnen eine praktische Einführung in die TF Framework. Ausgehend von einer Entwicklungsumgebung erstellen Sie ein einfaches und Funktionen hinzufügen.

In diesem Tutorial wird der Testentwicklungsprozess als eine Reihe von Übungen vorgestellt. die jeweils aus mehreren Schritten bestehen, und Ihre Konfiguration optimieren. Den Beispielcode, den Sie für den Test benötigen Konfiguration bereitgestellt und der Titel jeder Übung ist mit einem , in dem die mit diesem Schritt verbundenen Rollen beschrieben werden:

  • D für Entwickler
  • I für Integrator
  • R für Test-Ausführer

Nach Abschluss des Tutorials haben Sie eine funktionierende TF-Konfiguration. und viele wichtige Konzepte im TF-Framework verstehen.

Gewerkschaftsföderation einrichten

Weitere Informationen zum Einrichten der TF-Entwicklungsumgebung finden Sie unter Maschine Einrichtung: Im weiteren Verlauf dieser Anleitung wird davon ausgegangen, dass Sie eine geöffnete Shell haben, die zuvor in der TF-Umgebung initialisiert.

Der Einfachheit halber veranschaulicht dieses Tutorial das Hinzufügen einer Konfiguration und zur Kernbibliothek des TF-Frameworks hinzufügen. Dies kann auf die Entwicklung von Module außerhalb des Quellbaums, indem Sie die getauschte JAR-Datei kompilieren und dann Ihre Module mit dieser JAR-Datei zu vergleichen.

Testklasse erstellen (D)

Lassen Sie uns einen Hello World-Test erstellen, der einfach eine Nachricht an stdout ausgibt. A im Rahmen des Tradefed-Tests IRemoteTest . Hier sehen Sie eine Implementierung für 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!");
    }
}

Diesen Beispielcode speichern unter <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java und neu von der Shell aus getauscht:

m -jN

Beachten Sie, dass im obigen Beispiel CLog.i verwendet wird, um die Ausgabe an die Konsole zu leiten. Mehr Informationen zur Abholzung in der Gewerkschaftsföderation werden unter Protokollierung (D, I, R) beschrieben.

Wenn der Build nicht erfolgreich ist, wenden Sie sich an Maschine Einrichtung, um keinen Schritt zu verpassen.

Konfiguration erstellen (I)

Gewerkschaftstests werden ausführbar gemacht, indem ein Configuration, eine XML-Datei, die angibt, auf welchem welche anderen Module erforderlich sind und in welchem Reihenfolge.

Erstellen wir nun eine neue Konfiguration für HelloWorldTest (beachten Sie die gesamte Klasse „HelloWorldTest“):

<configuration description="Runs the hello world test">
    <test class="com.android.tradefed.example.HelloWorldTest" />
</configuration>

Speichern Sie diese Daten in einer helloworld.xml-Datei auf Ihrem lokalen Computer Dateisystem (z.B. /tmp/helloworld.xml). TF parst die Konfigurations-XML-Datei (auch bekannt als config) laden Sie die angegebene Klasse mithilfe von reflektieren, instanziieren, in eine IRemoteTest umwandeln und ihre run-Methode.

Konfiguration ausführen (R)

Starten Sie über Ihre Shell die Tradefed-Konsole:

tradefed.sh

Achten Sie darauf, dass ein Gerät mit dem Hostcomputer verbunden und für den Tradefed sichtbar ist:

tf> list devices
Serial            State      Product   Variant   Build   Battery
004ad9880810a548  Available  mako      mako      JDQ39   100

Konfigurationen können mit dem run <config> ausgeführt werden Console-Befehl. Hier sind ein paar Vorschläge:

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!

Es sollte "Hello, TF World!" angezeigt werden. im Terminal angezeigt.

Ob ein Befehl ausgeführt wurde, können Sie mit list invocations oder l i in die Eingabeaufforderung der Konsole ein. Es sollte keine Ausgabe ausgegeben werden. Sind die Befehle derzeit angezeigt wird, werden sie wie folgt angezeigt:

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}'

Konfiguration zum Klassenpfad hinzufügen (D, I, R)

Zur Vereinfachung der Bereitstellung können Sie Konfigurationen auch im getauschten JARs selbst. Tradefed erkennt automatisch alle Konfigurationen in config-Ordner im Klassenpfad.

Verschieben Sie zur Veranschaulichung die Datei helloworld.xml in den Tradefed Core Library (<tree>/tools/tradefederation/core/res/config/example/helloworld.xml) Erstelle die Tradefed-Konsole neu, starte die eingetauschte Konsole neu und bitte dann, die Tradefed-Konsole anzuzeigen. Liste der Konfigurationen aus dem Klassenpfad:

tf> list configs
[…]
example/helloworld: Runs the hello world test

Sie können die Konfiguration für blogger jetzt mit folgendem Befehl ausführen:

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!

Mit einem Gerät interagieren (D, R)

Bisher macht unser HelloWorldTest noch nichts Interessantes. Tradefed Spezialgebiet ist die Durchführung von Tests mit Android-Geräten. Fügen wir also ein Android-Gerät hinzu. für den Test.

Tests können mithilfe von TestInformation (vorausgesetzt) einen Verweis auf ein Android-Gerät abrufen. vom Framework erstellt, wenn die Methode IRemoteTest#run aufgerufen wird.

Ändern wir nun die HelloWorldTest-Drucknachricht so, dass die Seriennummer das Gerät:

@Override
public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException {
    CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber());
}

Erstelle nun den Tradef-Code neu und sieh dir die Liste der Geräte an:

tradefed.sh
tf> list devices
Serial            State      Product   Variant   Build   Battery
004ad9880810a548  Available  mako      mako      JDQ39   100

Notieren Sie sich die Seriennummer, die als Verfügbar aufgeführt ist. das entspricht das Gerät, das HelloWorld zugewiesen werden soll:

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

Die neue Druckmeldung mit der Seriennummer des .

Testergebnisse senden (D)

IRemoteTest meldet Ergebnisse durch Aufrufen von Methoden im ITestInvocationListener -Instanz, die der Methode #run bereitgestellt wird. Das TF-Framework selbst ist für die Meldung des Starts (über ITestInvocationListener#invocationStarted) und enden (über ITestInvocationListener#invocationEnded) für jeden Aufruf.

Ein Testlauf ist eine logische Sammlung von Tests. Um Testergebnisse zu melden, IRemoteTest ist dafür zuständig, den Start eines Testlaufs zu melden. Start und Ende jedes Tests sowie das Ende des Testlaufs.

So könnte die HelloWorldTest-Implementierung mit einem einzelnen nicht bestandenes Testergebnis.

@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 enthält mehrere IRemoteTest-Implementierungen, die Sie wiederverwenden können anstatt eine ganz neue Idee zu schreiben. Beispiel: Instrumentierungstest kann die Tests einer Android-App remote auf einem Android-Gerät ausführen, die und leiten diese Ergebnisse an ITestInvocationListener weiter. Weitere Informationen finden Sie unter Testen Typen:

Testergebnisse speichern (I)

Die standardmäßige Test-Listener-Implementierung für eine TF-Konfiguration ist TextResultReporter der die Ergebnisse eines Aufrufs an stdout ausgibt. Führen Sie zur Veranschaulichung den HelloWorldTest-Konfiguration aus dem vorherigen Abschnitt:

./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

Um die Ergebnisse eines Aufrufs an anderer Stelle, z. B. in einer Datei, zu speichern, geben Sie Benutzerdefinierte ITestInvocationListener-Implementierung mithilfe des result_reporter-Tag in Ihrer Konfiguration.

TF enthält auch die XmlResultReporter Listener, der Testergebnisse in einem Format, das dem folgenden Beispiel ähnelt, in eine XML-Datei schreibt: wird vom ant-JUnit-XML-Autor verwendet. Um den result_reporter in der Konfiguration, bearbeiten Sie die …/res/config/example/helloworld.xml Konfiguration:

<configuration description="Runs the hello world test">
    <test class="com.android.tradefed.example.HelloWorldTest" />
    <result_reporter class="com.android.tradefed.result.XmlResultReporter" />
</configuration>

Erstellen Sie jetzt den Tradefed neu und führen Sie das Hello World-Beispiel noch einmal aus:

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

Beachten Sie die Log-Nachricht, die besagt, dass eine XML-Datei generiert wurde. die sollte wie folgt aussehen:

<?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>

Sie können auch Ihre eigenen benutzerdefinierten Aufruf-Listener schreiben. Diese müssen Sie die ITestInvocationListener .

Tradefed unterstützt mehrere Aufruf-Listener, sodass Sie Testergebnisse senden können unabhängige Ziele zu erreichen. Geben Sie dazu einfach mehrere <result_reporter> Tags in Ihrer Konfiguration.

Abholzungseinrichtungen (D, I, R)

Die Protokollierungsfunktionen von TF bieten folgende Möglichkeiten:

  1. Protokolle vom Gerät erfassen (auch Geräte-Logcat genannt)
  2. Protokolle aus dem Trade Federation-Framework aufzeichnen, das auf dem Hostcomputer ausgeführt wird (Hostprotokoll)

Das TF-Framework erfasst automatisch den Logcat vom zugewiesenen Gerät und zur Verarbeitung an den Aufruf-Listener gesendet. Anschließend speichert XmlResultReporter den erfassten Geräte-Logcat als Datei.

TF-Hostprotokolle werden mithilfe der Methode CLog-Wrapper für die ddmlib-Protokollklasse. Lassen Sie uns die vorherigen System.out.println-Aufruf in HelloWorldTest an einen Anruf in CLog:

@Override
public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
    CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());

CLog verarbeitet die Stringinterpolation direkt, ähnlich wie String.format. Wenn Sie TF neu erstellen und neu ausführen, sollten Sie Lognachricht in stdout:

tf> run example/helloworld
…
05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
…

Standardmäßig gehandelt Ausgabe-Hostprotokoll Nachrichten an stdout. TF enthält auch eine Protokollimplementierung, die schreibt, Nachrichten in eine Datei: FileLogging: Um das Datei-Logging hinzuzufügen, fügen Sie der Konfiguration ein logger-Tag hinzu und geben Sie dabei die Variable Vollständiger Kursname von 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>

Erstellen Sie nun einen neuen Build und führen Sie das Beispiel helloworld noch einmal aus:

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
…

Die Lognachricht gibt den Pfad des Hostprotokolls an. Beim Aufrufen sollte Ihre HelloWorldTest-Lognachricht enthalten:

more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt

Beispielausgabe:

…
05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548

Verarbeitungsoptionen (D, I, R)

Objekte, die aus einer TF-Konfiguration geladen wurden (auch Konfigurationsobjekte genannt) kann auch Daten aus Befehlszeilenargumenten empfangen, indem die @Option-Anmerkung.

Für die Teilnahme wendet eine Konfigurationsobjektklasse das @Option an. -Anmerkung zu einem Mitgliederfeld hinzu und gibt ihm einen eindeutigen Namen. Dadurch kann Mitglied-Feldwert, der über eine Befehlszeilenoption (sowie fügt diese Option dem Konfigurationshilfesystem automatisch hinzu.

Hinweis:Nicht alle Feldtypen werden unterstützt. Für eine Beschreibung der unterstützten Typen, siehe OptionSetter

Fügen Sie HelloWorldTest eine @Option hinzu:

@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";

Als Nächstes fügen wir eine Lognachricht hinzu, um den Wert der Option HelloWorldTest ein, damit wir prüfen können, ob es richtig empfangen wurde:

@Override
public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
    …
    CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);

Erstellen Sie schließlich TF neu und führen Sie helloworld aus. sollten Sie eine Log-Nachricht mit dem Standardwert für my_option:

tf> run example/helloworld
…
05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'

Werte über die Befehlszeile übergeben

Übergeben Sie einen Wert für my_option. sollten Sie sehen, my_option mit diesem Wert gefüllt:

tf> run example/helloworld --my_option foo
…
05-24 18:33:44 I/HelloWorldTest: I received option 'foo'

TF-Konfigurationen beinhalten auch ein Hilfesystem, das automatisch Hilfetext für @Option-Felder. Probieren Sie es jetzt aus. Hilfetext zu 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.

Beachten Sie die Meldung "Nur die wichtigen Optionen drucken". Um die Option „Hilfe für mehr Ordnung“, verwendet TF das Attribut Option#importance, bestimmen, ob ein bestimmter Hilfetext für das Feld @Option angezeigt wird, wenn --help ist angegeben. --help-all zeigt immer Hilfe zu Alle @Option-Felder, unabhängig von ihrer Wichtigkeit. Weitere Informationen finden Sie unter Option.Wichtigkeit:

Werte aus einer Konfiguration übergeben

Sie können innerhalb der Konfiguration auch einen Optionswert angeben, indem Sie einen <option name="" value="">-Element. Testen mit helloworld.xml:

<test class="com.android.tradefed.example.HelloWorldTest" >
    <option name="my_option" value="fromxml" />
</test>

Die Neuerstellung und Ausführung von helloworld sollte jetzt folgende Ausgabe erzeugen:

05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'

Die Konfigurationshilfe sollte ebenfalls aktualisiert werden, um den Standardwert von my_option:

tf> run example/helloworld --help
  test options:
    -m, --my_option      this is the option's help text Default: fromxml.

Andere Konfigurationsobjekte, die in der Konfiguration von helloworld enthalten sind, z. B.: FileLogger, auch Optionen akzeptieren. Die Option --log-level-display ist interessant, weil damit die Logs gefiltert werden, die in stdout erscheinen. Sie haben vielleicht schon die Nachricht "Hello, TF Welt! Ich habe Gerät ..." dass Log-Nachrichten in stdout nicht mehr angezeigt wurden, Zu FileLogger gewechselt. Sie können die Ausführlichkeit wird in stdout protokolliert, indem das Argument --log-level-display übergeben wird.

Probieren Sie es jetzt aus. Die Meldung "Ich habe ein Gerät" sollte angezeigt werden. Log-Nachricht erscheinen am stdout, werden zusätzlich zum Protokollieren in einer Datei:

tf> run example/helloworld --log-level-display info
…
05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548

Das ist alles, Leute!

Zur Erinnerung: Wenn Sie bei einem Problem nicht weiterkommen, Handel Der Föderationsquellcode enthält viele nützliche Informationen, die in in der Dokumentation. Wenn das alles nicht funktioniert, fragen Sie in der Android-Plattform Google-Gruppe mit dem Handelsverbund im Betreff der Nachricht ein.