Contoh uji instrumentasi mandiri

Saat pengujian instrumentasi dimulai, paket targetnya dimulai ulang dengan kode instrumentasi yang dimasukkan dan dimulai untuk dieksekusi. Salah satu pengecualian adalah bahwa paket target di sini tidak dapat berupa framework aplikasi Android itu sendiri, seperti paket android, karena hal tersebut menyebabkan situasi paradoks saat framework Android perlu dimulai ulang, yang mendukung fungsi sistem, termasuk instrumentasi itu sendiri.

Artinya, uji instrumentasi tidak dapat memasukkan dirinya ke dalam framework Android, alias server sistem, untuk dieksekusi. Untuk menguji framework Android, kode pengujian hanya dapat memanggil platform API publik, atau yang diekspos menggunakan Android Interface Definition Language AIDL yang tersedia di hierarki sumber platform. Untuk kategori pengujian ini, menargetkan paket tertentu tidak berarti. Oleh karena itu, biasanya instrumentasi tersebut dideklarasikan untuk menargetkan paket aplikasi pengujiannya sendiri, seperti yang ditentukan dalam tag <manifest> AndroidManifest.xml-nya sendiri.

Bergantung pada persyaratan, paket aplikasi pengujian dalam kategori ini juga dapat:

  • Aktivitas paket yang diperlukan untuk pengujian.
  • Bagikan ID pengguna dengan sistem.
  • Ditandatangani dengan kunci platform.
  • Dikompilasi terhadap sumber framework, bukan SDK publik.

Kategori uji instrumentasi ini terkadang disebut sebagai instrumentasi mandiri. Berikut adalah beberapa contoh uji instrumentasi mandiri di sumber platform:

Contoh yang dibahas di sini adalah menulis uji instrumentasi baru dengan paket target yang ditetapkan pada paket aplikasi pengujiannya sendiri. Panduan ini menggunakan pengujian berikut sebagai contoh:

Sebaiknya jelajahi kode terlebih dahulu untuk mendapatkan tayangan kasar sebelum melanjutkan.

Menentukan lokasi sumber

Biasanya, tim Anda sudah memiliki pola tempat yang ditetapkan untuk memeriksa kode, dan tempat untuk menambahkan pengujian. Sebagian besar tim memiliki satu repositori git, atau berbagi satu dengan tim lain, tetapi memiliki subdirektori khusus yang berisi kode sumber komponen.

Dengan asumsi lokasi root untuk sumber komponen Anda berada di <component source root>, sebagian besar komponen memiliki folder src dan tests di bawahnya, dan beberapa file tambahan seperti Android.mk (atau dipecah menjadi file .mk tambahan), file manifes AndroidManifest.xml, dan file konfigurasi pengujian 'AndroidTest.xml'.

Karena Anda menambahkan pengujian baru, Anda mungkin perlu membuat direktori tests di samping komponen src, dan mengisinya dengan konten.

Dalam beberapa kasus, tim Anda mungkin memiliki struktur direktori lebih lanjut di bagian tests karena perlu mengemas berbagai rangkaian pengujian ke dalam setiap APK. Dan dalam hal ini, Anda harus membuat subdirektori baru di bagian tests.

Terlepas dari strukturnya, Anda akan mengisi direktori tests atau subdirektori yang baru dibuat dengan file yang mirip dengan yang ada di direktori instrumentation dalam contoh perubahan gerrit. Detail setiap file akan dijelaskan nanti dalam dokumen ini.

File manifes

Seperti halnya project aplikasi, setiap modul uji instrumentasi memerlukan file manifes bernama AndroidManifest.xml. Untuk menyertakan file ini secara otomatis menggunakan makefile inti BUILD_PACKAGE, sediakan file ini di samping file Android.mk untuk modul pengujian Anda.

Jika Anda tidak terbiasa dengan file AndroidManifest.xml, lihat Ringkasan Manifes Aplikasi

Berikut adalah contoh file AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:sharedUserId="android.uid.system"
  package="android.test.example.helloworld" >

    <application>
       <uses-library android:name="android.test.runner"/>
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Beberapa komentar pilihan pada file manifes:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

Atribut package adalah nama paket aplikasi: ini adalah ID unik yang digunakan framework aplikasi Android untuk mengidentifikasi aplikasi (atau dalam konteks ini: aplikasi pengujian Anda). Setiap pengguna dalam sistem hanya dapat menginstal satu aplikasi dengan nama paket tersebut.

Selain itu, atribut package ini sama dengan yang ditampilkan ComponentName#getPackageName(), dan juga atribut yang sama yang akan Anda gunakan untuk berinteraksi dengan berbagai sub-perintah pm menggunakan adb shell.

Perlu diketahui bahwa meskipun nama paket biasanya memiliki gaya yang sama dengan nama paket Java, nama tersebut sebenarnya hanya memiliki sedikit fungsi. Dengan kata lain, paket aplikasi (atau pengujian) Anda dapat berisi class dengan nama paket apa pun, meskipun di sisi lain, Anda dapat memilih kesederhanaan dan memiliki nama paket Java tingkat teratas di aplikasi atau pengujian yang identik dengan nama paket aplikasi.

android:sharedUserId="android.uid.system"

Ini mendeklarasikan bahwa pada waktu penginstalan, file APK ini harus diberi ID pengguna yang sama, yaitu identitas runtime, sebagai platform inti. Perhatikan bahwa hal ini bergantung pada apk yang ditandatangani dengan sertifikat yang sama dengan platform inti (lihat LOCAL_CERTIFICATE di bagian sebelumnya), tetapi keduanya adalah konsep yang berbeda:

  • beberapa izin atau API dilindungi tanda tangan, yang memerlukan sertifikat penandatanganan yang sama
  • beberapa izin atau API memerlukan identitas pengguna system pemanggil, yang memerlukan paket panggilan untuk membagikan ID pengguna dengan system, jika merupakan paket terpisah dari platform inti itu sendiri
<uses-library android:name="android.test.runner" />

Hal ini diperlukan untuk semua pengujian Instrumentasi karena class terkait dipaketkan dalam file library JAR framework terpisah, sehingga memerlukan entri classpath tambahan saat paket pengujian dipanggil oleh framework aplikasi.

android:targetPackage="android.test.example.helloworld"

Anda mungkin telah memperhatikan bahwa targetPackage di sini dideklarasikan sama dengan atribut package yang dideklarasikan dalam tag manifest file ini. Seperti yang disebutkan dalam dasar-dasar pengujian, kategori pengujian instrumentasi ini biasanya ditujukan untuk menguji API framework, sehingga tidak terlalu penting bagi pengujian tersebut untuk memiliki paket aplikasi yang ditargetkan secara spesifik, selain itu sendiri.

File konfigurasi sederhana

Setiap modul pengujian baru harus memiliki file konfigurasi untuk mengarahkan sistem build dengan metadata modul, dependensi waktu kompilasi, dan petunjuk pengemasan. Dalam sebagian besar kasus, opsi file Blueprint berbasis Soong sudah memadai. Untuk mengetahui detailnya, lihat Konfigurasi Pengujian Sederhana.

File konfigurasi yang kompleks

Untuk kasus yang lebih kompleks ini, Anda juga perlu menulis file konfigurasi pengujian untuk harness pengujian Android, Trade Federation.

Konfigurasi pengujian dapat menentukan opsi penyiapan perangkat khusus dan argumen default untuk menyediakan class pengujian. Lihat contohnya di /platform_testing/tests/example/instrumentation/AndroidTest.xml.

Snapshot disertakan di sini untuk memudahkan:

<configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>

Beberapa komentar pilihan pada file konfigurasi pengujian:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>

Tindakan ini akan memberi tahu Trade Federation untuk menginstal HelloWorldTests.apk ke perangkat target menggunakan target_preparer yang ditentukan. Ada banyak penyiapan target yang tersedia untuk developer di Trade Federation dan ini dapat digunakan untuk memastikan perangkat disiapkan dengan benar sebelum eksekusi pengujian.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

Ini menentukan class pengujian Trade Federation yang akan digunakan untuk menjalankan pengujian dan meneruskan paket di perangkat yang akan dijalankan dan framework runner pengujian yang dalam hal ini adalah JUnit.

Untuk mengetahui informasi selengkapnya, lihat Konfigurasi Modul Pengujian.

Fitur JUnit4

Menggunakan library android-support-test sebagai runner pengujian memungkinkan penggunaan class pengujian gaya JUnit4 baru, dan contoh perubahan gerrit berisi beberapa penggunaan fitur yang sangat mendasar. Lihat contohnya di /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java.

Meskipun pola pengujian biasanya khusus untuk tim komponen, ada beberapa pola penggunaan yang umumnya berguna.

@RunWith(JUnit4.class)
public class HelloWorldTest {

Perbedaan signifikan dalam JUnit4 adalah bahwa pengujian tidak lagi perlu mewarisi dari class pengujian dasar umum. Sebagai gantinya, Anda dapat menulis pengujian di class Java biasa dan menggunakan anotasi untuk menunjukkan penyiapan dan batasan pengujian tertentu. Dalam contoh ini, kita menginstruksikan bahwa class ini harus dijalankan sebagai pengujian JUnit4.

    @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...

Anotasi @Before dan @After digunakan pada metode oleh JUnit4 untuk melakukan penyiapan pra-pengujian dan penghapusan pasca-pengujian. Demikian pula, anotasi @BeforeClass dan @AfterClass digunakan pada metode oleh JUnit4 untuk melakukan penyiapan sebelum menjalankan semua pengujian dalam class pengujian, dan melakukan penguraian setelahnya. Perhatikan bahwa metode penyiapan dan penghapusan cakupan class harus statis. Untuk metode pengujian, tidak seperti di JUnit versi sebelumnya, metode tersebut tidak perlu lagi memulai nama metode dengan test, tetapi masing-masing harus dianotasi dengan @Test. Seperti biasa, metode pengujian harus bersifat publik, tidak mendeklarasikan nilai yang ditampilkan, tidak menggunakan parameter, dan dapat menampilkan pengecualian.

Akses class instrumentasi

Meskipun tidak tercakup dalam contoh hello world dasar, cukup umum bagi pengujian Android untuk memerlukan akses instance Instrumentation: ini adalah antarmuka API inti yang memberikan akses ke konteks aplikasi, API pengujian terkait siklus proses aktivitas, dan lainnya.

Karena pengujian JUnit4 tidak lagi memerlukan class dasar umum, Anda tidak lagi perlu mendapatkan instance Instrumentation melalui InstrumentationTestCase#getInstrumentation(). Sebagai gantinya, runner pengujian baru mengelolanya melalui InstrumentationRegistry tempat penyiapan kontekstual dan lingkungan yang dibuat oleh framework instrumentasi disimpan.

Untuk mengakses instance class Instrumentation, cukup panggil metode statis getInstrumentation() pada class InstrumentationRegistry:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Membangun dan menguji secara lokal

Untuk kasus penggunaan yang paling umum, gunakan Atest.

Untuk kasus yang lebih kompleks yang memerlukan penyesuaian yang lebih berat, ikuti petunjuk instrumentasi.