Przykład pełnego testu TF

Ten samouczek pokazuje, jak utworzyć aplikację „hello world” Federacja handlowa (tradefed lub TF) w ramach konfiguracji testu i zapewnia praktyczne wprowadzenie do TF; platformy. Zaczynając od środowiska programistycznego, utworzysz prosty plik konfiguracji i dodania funkcji.

Samouczek przedstawia proces opracowywania testu w formie zestawu ćwiczeń, składający się z kilku kroków, które pokazują, jak tworzyć i stopniowo i doprecyzować konfigurację. Cały przykładowy kod potrzebny do ukończenia testu i konfigurację, a w tytule każdego ćwiczenia znajduje się adnotacja list opisujący role związane z tym etapem:

  • D – programista.
  • I oznacza integratora
  • R – biegacz testowy

Po ukończeniu samouczka będziesz mieć działającą konfigurację TF i poznają wiele ważnych koncepcji z platformy TF.

Utwórz federację handlową

Szczegółowe informacje o konfigurowaniu środowiska programistycznego TF znajdziesz w artykule Maszyna Konfiguracja. W pozostałej części tego samouczka zakładamy, że masz otwartą powłokę, która została zainicjowano w środowisku TF.

Dla uproszczenia w tym samouczku przedstawiono dodawanie konfiguracji do podstawowej biblioteki platformy TF. Można to również rozszerzyć na tworzenie modułów poza drzewem źródłowym, kompilując plik JAR handel, a następnie kompilując modułów do tego pliku JAR.

Tworzenie klasy testowej (D)

Utwórzmy test hello world, który po prostu wysyła wiadomość do stdout. O w ramach testu związanego z handlem detalicznym zazwyczaj stosowane jest Test pilotażowy IRemoteTest za pomocą prostego interfejsu online. Oto implementacja 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!");
    }
}

Zapisz ten przykładowy kod w <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java i ponownie odbuduj handel z powłoki:

m -jN

Pamiętaj, że w powyższym przykładzie CLog.i służy do kierowania danych wyjściowych do konsoli. Więcej informacje o rejestrowaniu w Federacji Handlowej znajdziesz w artykule Logowanie (D, I, R).

Jeśli kompilacja się nie powiedzie, skontaktuj się z Maszyna Skonfiguruj, aby niczego nie przegapić.

Tworzenie konfiguracji (I)

Aby testy federacji handlowej były wykonywalne, należy utworzyć Configuration (Konfiguracja), plik XML instruujący handel, na którym który ma zostać uruchomiony, oraz które pozostałe moduły należy uruchomić i w jakiej zamówienie.

Utwórzmy nową konfigurację HelloWorldTest (zwróć uwagę na pełną nazwę obiektu HelloWorldTest):

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

Zapisz te dane w pliku helloworld.xml w dowolnym miejscu na urządzeniu lokalnym w systemie plików (np. /tmp/helloworld.xml). TF przeanalizuje pliku XML konfiguracji (inaczej config), wczytaj określoną klasę za pomocą: do refleksji, utwórz jej instancję, prześlij ją do IRemoteTest i wywołaj jej Metoda run.

Uruchom konfigurację (R)

Z poziomu powłoki uruchom konsolę handlową:

tradefed.sh

Sprawdź, czy urządzenie jest połączone z hostem i jest widoczne na potrzeby handlu elektronicznego:

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

Konfiguracje można wykonywać za pomocą: run <config> za pomocą polecenia konsoli. Spróbuj:

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!

Powinien wyświetlić się komunikat „Hello, TF World!”. dane wyjściowe w terminalu.

Aby sprawdzić, czy polecenie zostało uruchomione, użyj polecenia list invocations lub l i, ale nie powinien zostać wyświetlony żaden komunikat. Jeśli polecenia są obecnie wyświetlają się w następujący sposób:

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

Dodaj konfigurację do ścieżki klasy (D, I, R)

Dla wygody wdrożenia możesz również umieścić konfiguracje w pakiecie same pliki JAR. Tradefed automatycznie rozpoznaje wszystkie konfiguracje umieszczone w config w ścieżce klasy.

W tym celu przenieś plik helloworld.xml do Tradefed biblioteka główna (<tree>/tools/tradefederation/core/res/config/example/helloworld.xml). Zbuduj ponownie platformę handlową, uruchom ponownie konsolę Tradefed, a następnie poproś go o wyświetlenie lista konfiguracji ze ścieżki klasy:

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

Możesz teraz uruchomić konfigurację helloworld za pomocą polecenia:

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!

Interakcja z urządzeniem (D, R)

Jak dotąd nasz test HelloWorldTest nie robi nic interesującego. Tradefed specjalizuje się w przeprowadzaniu testów na urządzeniach z Androidem, więc dodajmy urządzenie do testu.

Testy mogą uzyskać odwołanie do urządzenia z Androidem za pomocą parametru TestInformation (pod warunkiem, że jest to możliwe) przez platformę, gdy wywoływana jest metoda IRemoteTest#run.

Zmodyfikujmy wiadomość drukowania HelloWorldTest, aby wyświetlała numer seryjny urządzenie:

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

Teraz przebuduj system Tradefed i sprawdź listę urządzeń:

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

zanotuj numer seryjny oznaczony jako Available (Dostępny); czyli urządzenie, które powinno zostać przydzielone do 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

Powinna wyświetlić się nowa wiadomość z numerem seryjnym urządzenia.

Wyślij wyniki testu (D)

IRemoteTest raportuje wyniki przez wywołania metod na Detektor ITestInvocationListener instancji udostępnianej do metody #run. Platforma TF odpowiedzialny za zgłoszenie początku (przy użyciu ITestInvocationListener#invocationStarted) i zakończ (przez ITestInvocationListener#invocationEnded) każdego wywołania.

Uruchomienie testów to logiczny zbiór testów. Aby zgłosić wyniki testu: IRemoteTest odpowiada za raportowanie rozpoczęcia testu. na początku i na końcu każdego testu oraz na końcu testu.

Tak może wyglądać implementacja HelloWorldTest z niepowodzenie testu.

@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 zawiera kilka implementacji IRemoteTest, które możesz wykorzystać zamiast pisać coś od podstaw. Przykład: Test narzędzi zdalnie uruchomić testy aplikacji na urządzeniu z Androidem, przeanalizować i przekazać je do ITestInvocationListener). Więcej informacji: Testuj Typy.

Wyniki testu sklepu (I)

Domyślna implementacja detektora testów w konfiguracji TF to TextResultReporter, który zrzuca wyniki wywołania do typu stdout. Aby to zilustrować, uruchom polecenie Konfiguracja HelloWorldTest z poprzedniej sekcji:

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

Aby zapisać wyniki wywołania w innym miejscu, na przykład w pliku, określ niestandardową implementację ITestInvocationListener za pomocą result_reporter w konfiguracji.

TF zawiera też Plik XMLResultReporter detektor, który zapisuje wyniki testów do pliku XML w formacie podobnym do tego, używane przez program zapisujący XML ant JUnit. Aby określić parametr result_reporter w parametrze edytuj …/res/config/example/helloworld.xml Konfiguracja:

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

Teraz przebuduj platformę handlową i uruchom ponownie przykładowy interfejs 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

zobaczysz komunikat logu z informacją, że został wygenerowany plik XML; wygenerowany plik powinien wyglądać tak:

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

Możesz też napisać własne niestandardowe detektory wywołań. musisz wdrożyć Detektor ITestInvocationListener za pomocą prostego interfejsu online.

Tradefed obsługuje wiele detektorów wywołań, dzięki czemu możesz wysyłać wyniki testu do wielu niezależnych miejsc docelowych. Aby to zrobić, wpisz wiele <result_reporter> tagów w Twojej konfiguracji.

Wycinki drzew (D, I, R)

Zasoby logowania TF umożliwiają:

  1. Przechwytywanie dzienników z urządzenia (inaczej logcat urządzenia)
  2. Rejestruj logi platformy federacji handlowej uruchomionej na hoście (inaczej dziennik hosta)

Platforma TF automatycznie przechwytuje plik logcat z przydzielonego urządzenia. i wysyła go do detektora wywołań w celu przetworzenia. Następnie XmlResultReporter zapisuje przechwycony dziennik urządzenia jako plik.

Dzienniki hosta TF są zgłaszane przy użyciu Kod CLog dla klasy ddmlib Log. Przekonwertujmy poprzednie wywołanie System.out.println w HelloWorldTest na CLog – połączenie:

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

CLog obsługuje bezpośrednio interpolację ciągów, podobnie jak String.format Po ponownym skompilowaniu i ponownym uruchomieniu pliku TF powinien wyświetlić się komunikat komunikat logu na stacji standardowej:

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

Domyślnie handel wyjściowy dziennik hosta wiadomości do stdout. TF zawiera również implementację logu, która zapisuje wiadomości do pliku: FileLogger. Aby dodać logowanie plików, dodaj do konfiguracji tag logger, określając pełna nazwa zajęć 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>

Teraz przebuduj i jeszcze raz uruchom przykład z 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
…

Komunikat logu wskazuje ścieżkę logu hosta, który po wyświetleniu powinien zawierać komunikat z dziennika HelloWorldTest:

more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt

Przykładowe dane wyjściowe:

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

Opcje obsługi (D, I, R)

Obiekty wczytane z konfiguracji TF (nazywane też obiektami konfiguracji) może też otrzymywać dane z argumentów wiersza poleceń za pomocą @Option adnotacja.

Aby można było korzystać z tej funkcji, klasa obiektu konfiguracji stosuje @Option do pola członka i nadaje mu unikalną nazwę. Dzięki temu: elementu członkowskiego do wypełnienia za pomocą opcji wiersza poleceń (oraz automatycznie doda tę opcję do systemu pomocy dotyczącej konfiguracji).

Uwaga: nie wszystkie typy pól są obsługiwane. Dla opis obsługiwanych typów, patrz OptionSetter.

Dodajmy @Option do 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";

Dodajmy komunikat logu, aby wyświetlić wartość opcji w HelloWorldTest, abyśmy mogli wykazać, że został otrzymany prawidłowo:

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

Na koniec odbuduj TF i uruchom helloworld. powinien zostać wyświetlony komunikat logu z Wartość domyślna parametru my_option:

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

Przekazuj wartości z wiersza poleceń

Przekaż wartość w polu my_option. zobaczysz Pole my_option zawiera tę wartość:

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

Konfiguracje TF obejmują również system pomocy, który automatycznie wyświetla tekst pomocy do pól @Option. Wypróbuj teraz, a powinien być widoczny tekst pomocy dla 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.

Zwróć uwagę na komunikat „Drukowanie tylko ważnych opcji”. Aby zmniejszyć polepsza bałagan, TF używa atrybutu Option#importance do Określenie, czy wyświetlać określony tekst pomocy dotyczący pola @Option, gdy Podano --help. --help-all zawsze wyświetla pomoc dotyczącą: wszystkich pól @Option niezależnie od ich ważności. Więcej informacji: Option.Ważność.

Przekazywanie wartości z konfiguracji

Wartość Option (opcję) możesz też określić w konfiguracji, dodając parametr <option name="" value=""> element. Przetestuj za pomocą helloworld.xml:

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

Ponowne skompilowanie i uruchomienie aplikacji helloworld powinny teraz przynieść takie dane wyjściowe:

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

Pomoc dotycząca konfiguracji powinna również zostać zaktualizowana, aby wskazać domyślną wartość my_option:

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

Inne obiekty konfiguracji uwzględnione w konfiguracji helloworld, takie jak FileLogger. Zaakceptuj też te opcje. Opcja Funkcja --log-level-display jest interesująca, ponieważ filtruje logi, które pojawiają się w stdout. Na początku samouczka zapewne zauważyłeś komunikat „Hello, TF”, Świat! Mam urządzenie...” komunikat logu przestał być wyświetlany na standardowej sieci po przełączono na używanie FileLogger. Możesz zwiększyć szczegółowość logowanie do stdout przez przekazanie argumentu --log-level-display.

Spróbuj to zrobić teraz. Powinien wyświetlić się komunikat „Mam urządzenie”. komunikat logu pojawia się ponownie stdout, oprócz zalogowania się do pliku:

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

To wszystko!

Przypominamy, że jeśli na jakiś czas utkniesz, Handel Kod źródłowy federacji zawiera wiele przydatnych informacji, które nie są dostępne i dokumentacja. Jeśli wszystko zawiedzie, zapytaj na android-platforma Grupa dyskusyjna Google, „Federacja handlowa”. w temacie wiadomości.