Saat pengujian instrumentasi dimulai, paket targetnya akan
dimulai ulang dengan kode instrumentasi yang disuntikkan dan dimulai untuk dieksekusi. Satu
pengecualian adalah bahwa paket target di sini tidak boleh berupa framework aplikasi
Android itu sendiri, seperti paket android
, karena tindakan tersebut akan menyebabkan
situasi paradoks di mana framework Android perlu dimulai ulang, yang
mendukung fungsi sistem, termasuk instrumentasi itu sendiri.
Artinya, pengujian instrumentasi tidak dapat menyisipkan dirinya ke dalam framework Android, alias server sistem, untuk dieksekusi. Untuk menguji framework Android, kode pengujian hanya dapat memanggil permukaan API publik, atau yang diekspos menggunakan Android Interface Definition Language AIDL yang tersedia di hierarki sumber platform. Untuk kategori pengujian ini, tidak ada artinya menargetkan paket tertentu. Oleh karena itu, biasanya instrumentasi tersebut dideklarasikan untuk menargetkan paket aplikasi pengujiannya sendiri, seperti yang ditentukan dalam tag <manifest>
sendiri di AndroidManifest.xml
.
Bergantung pada persyaratan, paket aplikasi pengujian dalam kategori ini juga dapat:
- Aktivitas paket yang diperlukan untuk pengujian.
- Bagikan ID pengguna ke sistem.
- Ditandatangani dengan kunci platform.
- Dikompilasi terhadap sumber framework, bukan SDK publik.
Kategori uji instrumentasi ini terkadang disebut sebagai instrumentasi mandiri. Berikut beberapa contoh pengujian instrumentasi mandiri di sumber platform:
Contoh yang dibahas di sini adalah menulis pengujian instrumentasi baru dengan paket target yang ditetapkan di paket aplikasi pengujiannya sendiri. Panduan ini menggunakan pengujian berikut sebagai contoh:
Sebaiknya jelajahi kode terlebih dahulu untuk mendapatkan gambaran kasar sebelum melanjutkan.
Tentukan lokasi sumber
Biasanya, tim Anda sudah memiliki pola tempat yang ditetapkan untuk diperiksa dalam kode, dan tempat untuk menambahkan pengujian. Sebagian besar tim memiliki satu repositori git, atau membagikannya 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 dalamnya, dan beberapa
file tambahan seperti Android.mk
(atau dibagi menjadi file .mk
tambahan),
file manifes AndroidManifest.xml
, dan file konfigurasi pengujian
'AndroidTest.xml'.
Karena Anda menambahkan pengujian yang benar-benar 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 bawah tests
karena perlu mengemas rangkaian pengujian yang berbeda ke dalam APK individual. Dalam kasus ini, Anda harus membuat subdirektori baru di tests
.
Terlepas dari strukturnya, Anda akan mengisi direktori tests
atau subdirektori yang baru dibuat dengan file yang serupa dengan yang ada di direktori instrumentation
dalam perubahan gerrit contoh. Detail setiap
file akan dijelaskan nanti dalam dokumen ini.
File manifes
Seperti project aplikasi, setiap modul pengujian instrumentasi memerlukan
file manifes yang disebut AndroidManifest.xml
. Untuk menyertakan file ini secara otomatis menggunakan file make inti BUILD_PACKAGE
, sediakan file ini di samping file Android.mk
untuk modul pengujian Anda.
Jika Anda belum 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 catatan penting tentang 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 sama dengan yang akan Anda gunakan untuk berinteraksi dengan berbagai sub-perintah pm
menggunakan adb shell
.
Perhatikan bahwa meskipun nama paket biasanya memiliki gaya yang sama dengan nama paket Java, sebenarnya nama paket memiliki sangat sedikit kesamaan dengan nama paket Java. 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 atas di aplikasi atau pengujian yang identik dengan nama paket aplikasi.
android:sharedUserId="android.uid.system"
Hal ini menyatakan bahwa pada saat penginstalan, file APK ini harus diberi ID pengguna yang sama, yaitu identitas runtime, dengan 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
system
identitas pengguna pemanggil, yang mengharuskan paket panggilan membagikan ID pengguna dengansystem
, jika paket tersebut terpisah dari platform inti itu sendiri
<uses-library android:name="android.test.runner" />
Hal ini diperlukan untuk semua pengujian Instrumentation karena class terkait dikemas 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 memperhatikan bahwa targetPackage
di sini dideklarasikan sama dengan atribut
package
yang dideklarasikan dalam tag manifest
dari file ini. Seperti yang disebutkan dalam
dasar-dasar pengujian, kategori pengujian instrumentasi ini
biasanya ditujukan untuk menguji API framework, sehingga tidak terlalu berarti
jika memiliki paket aplikasi yang ditargetkan secara khusus, selain dirinya 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 cukup. 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 platform pengujian Android, Trade Federation.
Konfigurasi pengujian dapat menentukan opsi penyiapan perangkat khusus dan argumen default untuk menyediakan class pengujian. Lihat contoh 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 catatan pilihan pada file konfigurasi pengujian:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
Perintah ini memberi tahu Trade Federation untuk menginstal HelloWorldTests.apk ke perangkat target menggunakan target_preparer yang ditentukan. Ada banyak penyiap target yang tersedia untuk developer di Trade Federation dan 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 mengeksekusi pengujian dan meneruskan paket di perangkat yang akan dieksekusi 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 adopsi class pengujian gaya JUnit4 baru, dan contoh perubahan gerrit berisi beberapa penggunaan fitur yang sangat mendasar. Lihat contoh 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 pengujian tidak lagi harus diwarisi dari class pengujian dasar umum; sebagai gantinya, Anda menulis pengujian di class Java biasa dan menggunakan anotasi untuk menunjukkan penyiapan dan batasan pengujian tertentu. Dalam contoh ini, kita menginstruksikan agar class ini 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 penghentian pasca-pengujian. Demikian pula, anotasi @BeforeClass
dan
@AfterClass
digunakan pada metode oleh JUnit4 untuk melakukan penyiapan sebelum
mengeksekusi semua pengujian dalam class pengujian, dan penguraian setelahnya. Perhatikan bahwa
metode penyiapan dan penguraian cakupan class harus statis. Untuk metode pengujian,
tidak seperti pada versi JUnit sebelumnya, metode tersebut tidak lagi perlu memulai nama metode
dengan test
, melainkan setiap metode 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 dibahas dalam contoh hello world dasar, cukup umum bagi pengujian Android untuk memerlukan akses instance Instrumentation
: ini adalah antarmuka API inti yang menyediakan akses ke konteks aplikasi, API pengujian terkait siklus proses aktivitas, dan lainnya.
Karena pengujian JUnit4 tidak lagi memerlukan class dasar umum, Anda tidak perlu lagi 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()
Membuat dan menguji secara lokal
Untuk kasus penggunaan yang paling umum, gunakan Atest.
Untuk kasus yang lebih kompleks yang memerlukan penyesuaian lebih berat, ikuti petunjuk instrumentasi.