Google is committed to advancing racial equity for Black communities. See how.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Contoh Uji TF End-to-End

Tutorial ini memandu Anda dalam membuat konfigurasi uji Federasi Perdagangan (TF) "hello world" dan memberi Anda pengenalan langsung tentang kerangka kerja TF. Mulai dari lingkungan pengembangan, Anda akan membuat konfigurasi sederhana dan menambahkan fitur.

Tutorial ini menyajikan proses pengembangan pengujian sebagai serangkaian latihan, masing-masing terdiri dari beberapa langkah, yang mendemonstrasikan cara membuat dan menyempurnakan konfigurasi Anda secara bertahap. Semua kode contoh yang Anda perlukan untuk menyelesaikan konfigurasi tes disediakan, dan judul setiap latihan dianotasi dengan surat yang menjelaskan peran yang terlibat dalam langkah itu:

  • D untuk Pengembang
  • I untuk Integrator
  • R untuk Test Runner

Setelah menyelesaikan tutorial, Anda akan memiliki konfigurasi TF yang berfungsi dan memahami banyak konsep penting dalam kerangka TF.

Menyiapkan Federasi Dagang

Untuk detail tentang mengatur lingkungan pengembangan TF, lihat Pengaturan Mesin . Bagian selanjutnya dari tutorial ini mengasumsikan Anda memiliki shell terbuka yang telah diinisialisasi ke lingkungan TF.

Untuk mempermudah, tutorial ini mengilustrasikan penambahan konfigurasi dan class-nya ke pustaka inti kerangka TF. Ini dapat diperluas untuk mengembangkan modul di luar struktur kode sumber dengan mengompilasi JAR tradefed, kemudian mengompilasi modul Anda terhadap JAR tersebut.

Membuat kelas uji (D)

Mari kita buat tes hello world yang hanya membuang pesan ke stdout. Tes tradefed umumnya mengimplementasikan antarmuka IRemoteTest . Berikut implementasi untuk 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!");
    }
}

Simpan kode contoh ini ke <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java /tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java dan buat kembali tradefed dari shell Anda:

m -jN
.dll

Perhatikan bahwa CLog.i pada contoh di atas digunakan untuk mengarahkan output ke konsol. Informasi lebih lanjut tentang penebangan di Federasi Perdagangan dijelaskan dalam Penebangan (D, I, R) .

Jika build tidak berhasil, konsultasikan dengan Machine Setup untuk memastikan Anda tidak melewatkan satu langkah pun.

Membuat konfigurasi (I)

Tes Federasi Perdagangan dibuat dapat dieksekusi dengan membuat Konfigurasi , file XML yang menginstruksikan tradefed pada tes mana (atau tes) yang akan dijalankan, serta modul lain mana yang akan dijalankan dan dalam urutan apa.

Mari buat Konfigurasi baru untuk HelloWorldTest kita (catat nama kelas lengkap HelloWorldTest):

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

Simpan data ini ke file helloworld.xml mana saja di sistem file lokal Anda (misalnya /tmp/helloworld.xml ). TF akan mem-parsing file Konfigurasi XML (alias config ), memuat kelas yang ditentukan menggunakan refleksi, membuat instance, mentransmisikannya ke IRemoteTest , dan memanggil metode run -nya.

Menjalankan config (R)

Dari shell Anda, luncurkan konsol tradefed:

tradefed.sh

Pastikan perangkat terhubung ke mesin host dan terlihat tradefed:

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

Konfigurasi dapat dijalankan menggunakan perintah run <config> console. Mencoba:

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!

Anda akan melihat "Hello, TF World!" keluaran di terminal.

Anda dapat mengonfirmasi bahwa perintah telah selesai dijalankan dengan menggunakan list invocations atau li di prompt konsol, dan seharusnya tidak mencetak apa pun. Jika perintah sedang berjalan, mereka akan ditampilkan sebagai berikut:

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

Menambahkan konfigurasi ke classpath (D, I, R)

Untuk kenyamanan penerapan, Anda juga dapat menggabungkan konfigurasi ke dalam JAR yang ditukar itu sendiri. Tradefed secara otomatis mengenali semua konfigurasi yang ditempatkan di folder config di classpath.

Sebagai ilustrasi, pindahkan file helloworld.xml ke pustaka inti tradefed ( <tree>/tools/tradefederation/core/res/config/example/helloworld.xml ). Bangun kembali tradefed, mulai ulang konsol tradefed, lalu minta tradefed untuk menampilkan daftar konfigurasi dari classpath:

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

Anda sekarang dapat menjalankan konfigurasi helloworld menggunakan:

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!

Berinteraksi dengan perangkat (D, R)

Sejauh ini, HelloWorldTest kami tidak melakukan sesuatu yang menarik. Spesialisasi Tradefed adalah menjalankan pengujian menggunakan perangkat Android, jadi mari tambahkan perangkat Android ke pengujian.

Pengujian bisa mendapatkan referensi ke perangkat Android dengan menggunakan TestInformation , yang disediakan oleh framework saat metode IRemoteTest#run dipanggil.

Mari kita ubah pesan cetak HelloWorldTest untuk menampilkan nomor seri perangkat:

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

Sekarang buat kembali tradefed dan periksa daftar perangkat:

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

Catat nomor seri yang terdaftar sebagai Tersedia ; itu adalah perangkat yang harus dialokasikan ke 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

Anda akan melihat pesan cetak baru yang menampilkan nomor seri perangkat.

Mengirim hasil tes (D)

IRemoteTest melaporkan hasil dengan memanggil metode pada instance ITestInvocationListener yang diberikan ke metode #run . Framework TF itu sendiri bertanggung jawab untuk melaporkan awal (melalui ITestInvocationListener # invocationStarted ) dan akhir (melalui ITestInvocationListener # invocationEnded ) dari setiap Invocation.

Uji coba adalah kumpulan pengujian logis. Untuk melaporkan hasil pengujian, IRemoteTest bertanggung jawab untuk melaporkan awal pengujian, awal dan akhir setiap pengujian, dan akhir pengujian.

Berikut tampilan implementasi HelloWorldTest dengan satu hasil pengujian yang gagal.

@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 menyertakan beberapa implementasi IRemoteTest yang dapat Anda gunakan kembali alih-alih menulis sendiri dari awal. Misalnya, InstrumentationTest bisa menjalankan pengujian aplikasi Android dari jarak jauh pada perangkat Android, mengurai hasilnya, dan meneruskan hasil tersebut ke ITestInvocationListener ). Untuk detailnya, lihat Jenis Tes .

Menyimpan hasil tes (I)

Implementasi pemroses pengujian default untuk konfigurasi TF adalah TextResultReporter , yang membuang hasil pemanggilan ke stdout. Sebagai ilustrasi, jalankan konfigurasi HelloWorldTest dari bagian sebelumnya:

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

Untuk menyimpan hasil pemanggilan di tempat lain, seperti di file, tentukan implementasi ITestInvocationListener kustom menggunakan tag result_reporter dalam konfigurasi Anda.

TF juga menyertakan listener XmlResultReporter , yang menulis hasil pengujian ke file XML dalam format yang mirip dengan yang digunakan oleh penulis XML semut JUnit. Untuk menentukan result_reporter dalam konfigurasi, edit …/res/config/example/helloworld.xml config:

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

Sekarang buat kembali tradefed dan jalankan kembali sampel 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

Perhatikan pesan log yang menyatakan bahwa file XML telah dibuat; file yang dihasilkan akan terlihat seperti ini:

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

Anda juga dapat menulis pemroses permintaan khusus Anda sendiri — mereka hanya perlu mengimplementasikan antarmuka ITestInvocationListener .

Tradefed mendukung beberapa pemroses permintaan, sehingga Anda dapat mengirim hasil pengujian ke beberapa tujuan independen. Untuk melakukan ini, cukup tentukan beberapa <result_reporter> di konfigurasi Anda.

Penebangan (D, I, R)

Fasilitas logging TF mencakup kemampuan untuk:

  1. Tangkap log dari perangkat (alias logcat perangkat)
  2. Rekam log dari kerangka Federasi Perdagangan yang berjalan di mesin host (alias log host)

Framework TF secara otomatis menangkap logcat dari perangkat yang dialokasikan dan mengirimkannya ke pemroses permintaan untuk diproses. XmlResultReporter kemudian menyimpan logcat perangkat yang diambil sebagai file.

Log host TF dilaporkan menggunakan pembungkus CLog untuk kelas Log ddmlib. Mari kita ubah panggilan System.out.println sebelumnya di HelloWorldTest menjadi panggilan CLog :

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

CLog menangani interpolasi string secara langsung, mirip dengan String.format . Ketika Anda membangun kembali dan menjalankan kembali TF, Anda akan melihat pesan log di stdout:

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

Secara default, tradefed mengeluarkan pesan log host ke stdout . TF juga menyertakan implementasi log yang menulis pesan ke file: FileLogger . Untuk menambahkan logging file, tambahkan tag logger ke konfigurasi, dengan menentukan nama kelas lengkap 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>

Sekarang, bangun kembali dan jalankan contoh helloworld lagi:

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
…

Pesan log menunjukkan jalur log host, yang, jika dilihat, harus berisi pesan log HelloWorldTest Anda:

more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt

Contoh keluaran:

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

Opsi penanganan (D, I, R)

Objek yang dimuat dari Konfigurasi TF (alias Objek Konfigurasi ) juga dapat menerima data dari argumen baris perintah melalui penggunaan anotasi @Option .

Untuk berpartisipasi, kelas objek Konfigurasi menerapkan anotasi @Option ke bidang anggota dan memberinya nama unik. Ini memungkinkan nilai bidang anggota tersebut diisi melalui opsi baris perintah (dan juga secara otomatis menambahkan opsi itu ke sistem bantuan konfigurasi).

Catatan: Tidak semua jenis bidang didukung. Untuk penjelasan tentang tipe yang didukung, lihat OptionSetter .

Mari tambahkan @Option ke 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";

Selanjutnya, mari tambahkan pesan log untuk menampilkan nilai opsi di HelloWorldTest sehingga kita dapat menunjukkan bahwa itu diterima dengan benar:

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

Terakhir, bangun kembali TF dan jalankan helloworld; Anda akan melihat pesan log dengan nilai default my_option :

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

Meneruskan nilai dari baris perintah

Berikan nilai untuk my_option ; Anda akan melihat my_option diisi dengan nilai itu:

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

Konfigurasi TF juga menyertakan sistem bantuan, yang secara otomatis menampilkan teks bantuan untuk bidang @Option . Coba sekarang, dan Anda akan melihat teks bantuan untuk 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.

Perhatikan pesan tentang "mencetak hanya opsi yang penting". Untuk mengurangi kekacauan bantuan opsi, TF menggunakan atribut Option#importance untuk menentukan apakah akan menampilkan teks bantuan bidang @Option tertentu ketika --help ditentukan. --help-all selalu menampilkan bantuan untuk semua bidang @Option , terlepas dari kepentingannya. Untuk detailnya, lihat Option.Importance .

Meneruskan nilai dari konfigurasi

Anda juga dapat menentukan nilai Opsi dalam konfigurasi dengan menambahkan elemen <option name="" value=""> . Uji menggunakan helloworld.xml :

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

Membangun kembali dan menjalankan helloworld sekarang akan menghasilkan keluaran ini:

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

Bantuan konfigurasi juga harus diperbarui untuk menunjukkan nilai default my_option :

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

Objek konfigurasi lain yang termasuk dalam konfigurasi helloworld, seperti FileLogger , juga menerima opsi. Opsi --log-level-display menarik karena menyaring log yang muncul di stdout. Di awal tutorial, Anda mungkin telah memperhatikan pesan log "Halo, TF World! Saya punya perangkat… 'berhenti ditampilkan di stdout setelah kita beralih menggunakan FileLogger . Anda dapat meningkatkan verbositas logging ke stdout dengan meneruskan --log-level-display arg. --log-level-display .

Coba ini sekarang, dan Anda akan melihat pesan log 'Saya punya perangkat' muncul kembali di stdout, selain masuk ke file:

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

Itu saja, semuanya!

Sebagai pengingat, jika Anda terjebak pada sesuatu, kode sumber Federasi Perdagangan memiliki banyak informasi berguna yang tidak terungkap dalam dokumentasi. Jika semuanya gagal, coba tanyakan pada Google Group platform android , dengan "Federasi Perdagangan" di subjek pesan.