Contoh Tes Instrumen Sendiri

Saat uji instrumentasi dimulai, paket targetnya dimulai ulang dengan kode instrumentasi yang disuntikkan dan dimulai untuk eksekusi. Satu pengecualian adalah bahwa paket target di sini tidak boleh menjadi kerangka kerja aplikasi Android itu sendiri, yaitu paket android , karena hal itu akan mengarah pada situasi paradoks di mana kerangka kerja Android perlu dimulai ulang, yang mendukung fungsi sistem, termasuk instrumentasi. diri.

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

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

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

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

Contoh yang dibahas di sini adalah penulisan 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.

Memutuskan lokasi sumber

Biasanya tim Anda sudah memiliki pola tempat untuk memeriksa kode, dan tempat untuk menambahkan pengujian. Sebagian besar tim memiliki satu repositori git, 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 samping komponen 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 apk individu. Dan dalam hal ini, Anda harus membuat sub direktori baru di bawah tests .

Terlepas dari strukturnya, Anda pada akhirnya akan 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 secara lebih rinci setiap file.

File manifes

Sama seperti aplikasi biasa, setiap modul pengujian instrumentasi memerlukan file manifes. Jika Anda menamai file tersebut sebagai AndroidManifest.xml dan memberikannya di samping Android.mk untuk modul pengujian Anda, file tersebut akan disertakan secara otomatis oleh file makefile inti BUILD_PACKAGE .

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

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

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.

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

Perlu diketahui 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 dalam aplikasi atau pengujian yang 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 runtime, sebagai platform inti. Perhatikan bahwa ini bergantung pada apk yang ditandatangani dengan sertifikat yang sama dengan platform inti (lihat LOCAL_CERTIFICATE di bagian 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 penelepon, yang memerlukan paket panggilan untuk berbagi 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 terpisah, oleh karena itu memerlukan entri classpath tambahan saat paket pengujian dipanggil oleh kerangka kerja aplikasi.

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

Anda mungkin 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 uji instrumentasi ini biasanya ditujukan untuk menguji API kerangka kerja, jadi tidak terlalu berarti bagi mereka untuk memiliki paket aplikasi target tertentu, 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 instruksi pengemasan. Dalam kebanyakan kasus, opsi file Cetak Biru berbasis Soong sudah cukup. Untuk detailnya, lihat Konfigurasi Pengujian Sederhana .

File konfigurasi yang kompleks

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

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

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 Trade Federation untuk menginstal HelloWorldTests.apk ke perangkat target menggunakan target_preparer yang ditentukan. Ada banyak pembuat target yang tersedia untuk pengembang di Federasi Dagang dan ini dapat digunakan untuk memastikan perangkat telah diatur dengan benar sebelum pelaksanaan 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 Trade Federation yang akan digunakan untuk menjalankan pengujian dan meneruskan paket pada perangkat yang akan dieksekusi dan kerangka kerja pelari pengujian yang dalam kasus ini adalah JUnit.

Untuk informasi selengkapnya, lihat Konfigurasi Modul Pengujian .

fitur JUnit4

Menggunakan android-support-test library sebagai test runner memungkinkan adopsi kelas 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 .

Sementara pola pengujian biasanya khusus untuk tim komponen, ada beberapa pola penggunaan yang berguna secara umum.

@RunWith(JUnit4.class)
public class HelloWorldTest {

Perbedaan signifikan dalam JUnit4 adalah bahwa pengujian tidak lagi diperlukan untuk mewarisi dari kelas pengujian basis umum; sebagai gantinya, Anda menulis pengujian di kelas Java biasa dan menggunakan anotasi untuk menunjukkan penyiapan 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 dalam kelas pengujian, dan pembongkaran setelahnya. Perhatikan bahwa metode penyetelan ruang lingkup kelas dan pembongkaran harus statis. Untuk metode pengujian, tidak seperti versi JUnit sebelumnya, mereka tidak perlu lagi memulai nama metode dengan test , sebagai gantinya, masing-masing harus dianotasi dengan @Test . Seperti biasa, metode pengujian harus bersifat publik, mendeklarasikan tidak ada nilai kembalian, tidak mengambil parameter, dan dapat melontarkan pengecualian.

Penting : metode pengujian itu sendiri dianotasi dengan anotasi @Test ; dan perhatikan bahwa agar pengujian dapat dijalankan melalui APCT, pengujian tersebut harus dianotasi dengan ukuran pengujian: contoh metode yang dianotasi testHelloWorld sebagai @SmallTest . Anotasi dapat diterapkan pada lingkup metode, atau lingkup kelas.

Mengakses instrumentation

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

Karena pengujian JUnit4 tidak lagi memerlukan class 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 kerangka 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 rumit yang memerlukan penyesuaian lebih berat, ikuti petunjuk instrumentasi .