Contoh Tes Instrumen Sendiri

Ketika tes instrumentasi dimulai, paket targetnya dimulai ulang dengan kode instrumentasi yang disuntikkan dan dimulai untuk dieksekusi. Satu pengecualian adalah bahwa paket target di sini tidak dapat berupa kerangka kerja aplikasi Android itu sendiri, yaitu paket android , karena hal itu akan mengarah pada situasi paradoks di mana kerangka kerja Android perlu di-restart, yang mendukung fungsi sistem, termasuk instrumentasi. diri.

Ini berarti bahwa pengujian instrumentasi tidak dapat memasukkan dirinya sendiri ke dalam kerangka kerja Android, alias server sistem, untuk dieksekusi. Untuk menguji kerangka kerja Android, kode pengujian hanya dapat memanggil permukaan API publik, atau yang diekspos melalui AIDL Bahasa Definisi Antarmuka Android yang tersedia di hierarki sumber platform. Untuk kategori pengujian ini, tidak ada gunanya menargetkan paket tertentu. Oleh karena itu, biasanya instrumentasi tersebut dideklarasikan untuk menargetkan paket aplikasi pengujiannya sendiri, seperti yang didefinisikan dalam tag <manifest> sendiri di AndroidManifest.xml .

Tergantung pada persyaratannya, paket aplikasi uji dalam kategori ini juga dapat:

  • Bundel aktivitas yang diperlukan untuk pengujian.
  • Bagikan ID pengguna dengan sistem.
  • Ditandatangani dengan kunci platform.
  • Dikompilasi berdasarkan sumber kerangka kerja, bukan SDK publik.

Kategori tes instrumentasi ini kadang-kadang disebut sebagai instrumentasi mandiri. Berikut adalah beberapa contoh pengujian instrumen mandiri di sumber platform:

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

Disarankan untuk menelusuri kode terlebih dahulu untuk mendapatkan kesan kasar sebelum melanjutkan.

Menentukan lokasi sumber

Biasanya tim Anda sudah memiliki pola tempat untuk check-in kode, dan tempat untuk menambahkan tes. Sebagian besar tim memiliki repositori git tunggal, atau berbagi satu dengan tim lain tetapi memiliki sub direktori 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 tes baru, Anda mungkin perlu membuat direktori tests di sebelah komponen Anda src , dan mengisinya dengan konten.

Dalam beberapa kasus, tim Anda mungkin memiliki struktur direktori lebih lanjut yang sedang tests karena kebutuhan untuk mengemas rangkaian pengujian yang berbeda ke dalam masing-masing apk. Dan dalam hal ini, Anda harus membuat sub direktori baru di bawah tests .

Terlepas dari strukturnya, Anda akan berakhir mengisi direktori tests atau sub direktori yang baru dibuat dengan file yang mirip dengan apa yang ada di direktori instrumentation dalam contoh perubahan gerrit. Bagian di bawah ini akan menjelaskan detail lebih lanjut dari setiap file.

File manifes

Sama seperti aplikasi biasa, setiap modul pengujian instrumentasi membutuhkan file manifes. Jika Anda menamai file sebagai AndroidManifest.xml dan menyediakannya di sebelah Android.mk untuk modul pengujian Anda, itu akan disertakan secara otomatis oleh makefile inti BUILD_PACKAGE .

Sebelum melangkah lebih jauh, sangat disarankan untuk melalui Ikhtisar Manifes Aplikasi terlebih dahulu.

Ini memberikan gambaran umum tentang komponen dasar file manifes dan fungsinya. Lihat contohnya di platform_testing/tests/example/instrumentation/AndroidManifest.xml .

Sebuah snapshot disertakan di sini untuk kenyamanan:

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

    <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 pengidentifikasi unik yang digunakan kerangka kerja 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.

Lebih lanjut, atribut package ini sama dengan yang dikembalikan oleh ComponentName#getPackageName() , dan juga sama yang akan Anda gunakan untuk berinteraksi dengan berbagai sub perintah pm melalui adb shell .

Harap perhatikan juga bahwa meskipun nama paket biasanya memiliki gaya yang sama dengan nama paket Java, sebenarnya sangat sedikit hubungannya dengan itu. Dengan kata lain, paket aplikasi (atau pengujian) Anda mungkin berisi kelas dengan nama paket apa pun, meskipun di sisi lain, Anda dapat memilih kesederhanaan dan memiliki nama paket Java tingkat atas di aplikasi Anda atau pengujian identik dengan nama paket aplikasi.

android:sharedUserId="android.uid.system"

Ini menyatakan bahwa pada saat penginstalan, apk ini harus diberikan id pengguna yang sama, yaitu identitas waktu proses, sebagai platform inti. Perhatikan bahwa ini tergantung pada apk yang ditandatangani dengan sertifikat yang sama dengan platform inti (lihat LOCAL_CERTIFICATE di bagian di atas), namun konsepnya berbeda:

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

Ini diperlukan untuk semua pengujian Instrumentasi karena kelas terkait dikemas dalam file pustaka jar kerangka kerja terpisah, oleh karena itu memerlukan entri classpath tambahan saat paket uji dipanggil oleh kerangka kerja aplikasi.

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

Anda mungkin telah memperhatikan bahwa targetPackage di sini dinyatakan sama dengan atribut package yang dideklarasikan dalam tag manifest file ini. Seperti disebutkan dalam dasar- dasar pengujian , kategori pengujian instrumentasi ini biasanya ditujukan untuk menguji API kerangka kerja, jadi tidak terlalu berarti bagi mereka untuk memiliki paket aplikasi bertarget khusus, selain itu sendiri.

File konfigurasi sederhana

Setiap modul pengujian baru harus memiliki file konfigurasi untuk mengarahkan sistem pembangunan dengan metadata modul, dependensi waktu kompilasi, dan instruksi pengemasan. Dalam kebanyakan kasus, opsi file Blueprint berbasis Soong sudah cukup. Untuk detailnya, lihat Konfigurasi Pengujian Sederhana .

File konfigurasi kompleks

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

Konfigurasi pengujian dapat menentukan opsi pengaturan perangkat khusus dan argumen default untuk memasok kelas pengujian. Lihat contohnya di /platform_testing/tests/example/instrumentation/AndroidTest.xml .

Sebuah snapshot disertakan di sini untuk kenyamanan:

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

Ini memberitahu Federasi Perdagangan untuk menginstal HelloWorldTests.apk ke perangkat target menggunakan target_preparer yang ditentukan. Ada banyak penyiapan target yang tersedia untuk pengembang di Federasi Perdagangan dan ini dapat digunakan untuk memastikan perangkat diatur 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 kelas pengujian Federasi Perdagangan yang akan digunakan untuk menjalankan pengujian dan lolos dalam paket pada perangkat yang akan dieksekusi dan kerangka kerja runner pengujian yang dalam hal ini adalah JUnit.

Untuk informasi selengkapnya, lihat Konfigurasi Modul Uji .

fitur JUnit4

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

Sementara 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 tes tidak lagi diperlukan untuk mewarisi dari kelas tes dasar umum; sebagai gantinya, Anda menulis pengujian di kelas Java biasa dan menggunakan anotasi untuk menunjukkan pengaturan dan batasan pengujian tertentu. Dalam contoh ini, kami menginstruksikan bahwa kelas 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() {
    ...

@Before dan @After digunakan pada metode oleh JUnit4 untuk melakukan penyiapan pra pengujian dan pembongkaran pasca pengujian. Demikian pula, anotasi @BeforeClass dan @AfterClass digunakan pada metode oleh JUnit4 untuk melakukan penyiapan sebelum menjalankan semua pengujian di kelas pengujian, dan pembongkaran setelahnya. Perhatikan bahwa metode penyiapan ruang lingkup kelas dan pembongkaran harus statis. Adapun metode pengujian, tidak seperti di versi JUnit sebelumnya, mereka tidak perlu lagi memulai nama metode dengan test , sebaliknya, masing-masing harus dianotasi dengan @Test . Seperti biasa, metode pengujian harus bersifat publik, menyatakan tidak ada nilai yang dikembalikan, tidak mengambil parameter, dan dapat mengeluarkan pengecualian.

Penting : metode pengujian itu sendiri dijelaskan dengan penjelasan @Test ; dan perhatikan bahwa untuk pengujian yang akan dijalankan melalui APCT, pengujian tersebut harus diberi keterangan dengan ukuran pengujian: contoh metode beranotasi testHelloWorld sebagai @SmallTest . Anotasi dapat diterapkan pada lingkup metode, atau lingkup kelas.

Mengakses instrumentation

Meskipun tidak tercakup dalam contoh hello world dasar, pengujian Android cukup umum memerlukan instance Instrumentation akses: ini adalah antarmuka API inti yang menyediakan akses ke konteks aplikasi, API pengujian terkait siklus hidup aktivitas, dan banyak lagi.

Karena pengujian JUnit4 tidak lagi memerlukan kelas dasar umum, instance Instrumentation tidak lagi diperlukan 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 kelas Instrumentation , cukup panggil metode statis getInstrumentation() pada kelas InstrumentationRegistry :

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Bangun dan uji secara lokal

Untuk kasus penggunaan yang paling umum, gunakan Atest .

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