3.2: Menguji Aplikasi dengan Pengujian Unit

Daftar Isi:

Menguji kode dapat membantu menemukan bug secepat mungkin selama development, saat yang paling murah untuk menangani bug — dan meningkatkan ketangguhan kode saat aplikasi semakin besar dan kompleks. Dengan pengujian terhadap kode, Anda bisa melatih sebagian kecil aplikasi dalam isolasi, dan dengan cara yang otomatis dan dapat diulang.

Android Studio dan Android Testing Support Library mendukung beberapa jenis pengujian dan framework pengujian. Dalam praktik ini Anda akan menjelajahi fungsionalitas bawaan Android Studio untuk pengujian, dan belajar menulis serta menjalankan pengujian unit lokal.

Pengujian unit lokal adalah pengujian yang dikompilasi dan dijalankan sepenuhnya pada komputer lokal Anda dengan Java Virtual Machine (JVM). Gunakan pengujian unit lokal untuk menguji bagian aplikasi Anda (seperti logika internal) yang tidak membutuhkan akses ke framework Android atau perangkat atau emulator Android, atau bagian yang membuat objek palsu ("tiruan") yang berpura-pura berperilaku seperti framework yang setara. Pengujian unit ditulis dengan JUnit, framework pengujian unit yang umum untuk Java.

Yang harus sudah Anda KETAHUI

Dari praktik sebelumnya, Anda harus sudah memahami:

  • Cara membuat proyek di Android Studio.
  • Komponen utama Android Studio (manifes, sumber daya, file Java, file gradle).
  • Cara membuat dan menjalankan aplikasi.

Yang akan Anda PELAJARI

  • Cara mengelola dan menjalankan pengujian di Android Studio.
  • Apa itu pengujian unit dan cara menulis pengujian unit untuk kode.
  • Cara membuat dan menjalankan pengujian unit lokal di Android Studio.

Yang akan Anda LAKUKAN

  • Menjalankan pengujian awal di aplikasi SimpleCalc.
  • Menambahkan pengujian lainnya ke aplikasi SimpleCalc.
  • Menjalankan pengujian unit untuk melihat hasilnya.

Ringkasan Aplikasi

Praktik ini menggunakan aplikasi SimpleCalc yang sama dengan aplikasi dari praktik sebelumnya. Anda bisa memodifikasi aplikasi ini dalam aplikasi langsung, atau salin proyek Anda ke aplikasi baru.

Tugas 1. Menjelajahi dan menjalankan SimpleCalc di Android Studio

Anda menulis dan menjalankan pengujian (pengujian unit dan pengujian berinstrumen) di dalam Android Studio, di samping kode untuk aplikasi. Setiap proyek Android baru menyertakan kelas contoh dasar untuk pengujian yang bisa Anda perpanjang atau ganti dengan penggunaan sendiri.

Dalam tugas ini kita akan kembali ke aplikasi SimpleCalc, yang menyertakan kelas pengujian unit dasar.

1.1 Menjelajahi rangkaian sumber dan SimpleCalc

Rangkaian sumber adalah kumpulan kode terkait dalam proyek untuk target membangun yang berbeda atau "variasi" lainnya dari aplikasi Anda. Saat Android Studio membuat proyek, Android Studio membuat tiga rangkaian sumber:

  • Rangkaian sumber utama, untuk kode dan sumber daya aplikasi Anda.
  • Rangkaian sumber pengujian, untuk pengujian unit lokal aplikasi.
  • Rangkaian sumber androidTest, untuk pengujian berinstrumen Android.

Dalam tugas ini Anda akan mempelajari bagaimana rangkaian sumber ditampilkan dalam Android Studio, memeriksa konfigurasi gradle untuk pengujian, dan menjalankan pengujian untuk aplikasi SimpleCalc. Anda akan menggunakan rangkaian sumber androidTest dengan lebih detail pada praktik berikutnya.

  1. Membuka proyek SimpleCalc dalam Android Studio jika belum. Jika belum memiliki SimpleCalc Anda bisa menemukannya di [tautan unduhan] ini(https://github.com/google-developer-training/android-fundamentals/tree/master/SimpleCalc).
  2. Buka tampilan Project, dan perluas folder aplikasi dan java.

    Folder java dalam tampilan Android mencantumkan semua rangkaian sumber dalam aplikasi menurut nama paket (com.android.example.simplecalc), dengan pengujian dan androidTest ditampilkan dalam tanda kurung setelah nama paket. Dalam aplikasi SimpleCalc, hanya rangkaian sumber utama dan pengujian yang digunakan. Rangkaian sumber

  3. Luaskan folder com.android.example.simplecalc (test).

    Ini adalah folder tempat Anda meletakkan pengujian unit lokal aplikasi. Android Studio membuat kelas pengujian contoh untuk Anda dalam folder ini untuk proyek baru, tetapi untuk SimpleCalc, kelas pengujiannya disebut CalculatorTest.

  4. Buka CalculatorTest.java.
  5. Periksa kode dan catat hal-hal berikut ini:

    • Satu-satunya impor adalah dari paket org.junit, org.hamcrest, dan android.test. Tidak ada dependensi pada kelas framework Android di sini.
    • Anotasi @RunWith(JUnit4.class) menunjukkan runner yang akan digunakan untuk menjalankan pengujian dalam kelas ini. Runner pengujian adalah pustaka atau serangkaian alat yang memungkinkan pengujian terjadi dan hasilnya dicetak ke log. Untuk pengujian dengan penyiapan atau persyaratan infrastruktur yang lebih rumit (seperti Espresso), Anda akan menggunakan runner pengujian yang berbeda. Untuk contoh berikut kita menggunakan runner pengujian JUnit4 dasar.
    • Anotasi @SmallTest menunjukkan bahwa semua pengujian dalam kelas ini adalah pengujian unit yang tidak memiliki dependensi dan berjalan dalam milidetik. Anotasi @SmallTest, @MediumTest, dan @LargeTest adalah konvensi yang memudahkan membundel grup pengujian ke dalam kelompok fungsionalitas yang serupa.
    • Metode setUp() digunakan untuk menyiapkan lingkungan sebelum pengujian, dan menyertakan anotasi @Before. Dalam hal ini, penyiapan membuat instance baru kelas Calculator dan menetapkannya ke variabel anggota mCalculator.
    • Metode addTwoNumbers() adalah pengujian yang sebenarnya, dan dianotasi dengan @Test. Hanya metode dalam kelas tes yang memiliki anotasi @Test yang dianggap pengujian bagi runner pengujian. Perhatikan bahwa metode pengujian konvensi tidak termasuk kata "test".
    • Baris pertama addTwoNumbers() memanggil metode add() dari kelas Calculator. Anda hanya bisa menguji metode yang bersifat publik atau dilindungi paket. Dalam hal ini Calculator adalah kelas publik dengan metode publik, jadi semuanya berjalan baik.
    • Baris kedua adalah pernyataan untuk pengujian. Pernyataan adalah ekspresi yang harus mengevaluasi dan menghasilkan benar untuk lulus pengujian. Dalam hal ini, pernyataannya adalah bahwa hasil yang Anda dapatkan dari metode penambahan (1 + 1) cocok dengan nomor 2 yang diberikan. Anda akan mempelajari selengkapnya tentang cara membuat pernyataan nanti dalam praktik ini.

1.2 Menjalankan pengujian dalam Android Studio

Dalam tugas ini Anda akan menjalankan pengujian unit dalam folder pengujian dan melihat keluaran untuk pengujian yang berhasil dan gagal.

  1. Dalam tampilan proyek, klik kanan kelas CalculatorTest dan pilih Run 'CalculatorTest'.

    Proyek membangun, jika perlu, dan tampilan pengujian muncul di bagian bawah layar. Di bagian atas layar, tarik turun (untuk konfigurasi eksekusi yang tersedia) juga berubah menjadi CalculatorTest. Menjalankan konfigurasi untuk CalculatorTest

    Semua pengujian dalam kelas CalculatorTest berjalan, dan jika pengujian tersebut berhasil, bilah kemajuan di bagian atas tampilan akan berubah menjadi warna hijau. (Dalam hal ini, hanya ada satu pengujian saat ini.) Pesan status dalam footer juga melaporkan "Tests Passed."
    Semua pengujian berhasil

  2. Dalam kelas CalculatorTest, ubah pernyataan dalam addTwoNumbers() ke:
    assertThat(resultAdd, is(equalTo(3d)));
    
  3. Dalam menu tarik turun run configurations di bagian atas layar, pilih CalculatorTest (jika belum dipilih) dan klik Run Ikon Run.

    Pengujian berjalan lagi seperti sebelumnya, namun kali ini pernyataannya gagal (3 tidak sama dengan 1 + 1.) Bilah kemajuan dalam tampilan berjalan berubah menjadi merah, dan log pengujian menunjukkan di mana (pernyataan) gagal dan alasannya.

  4. Ubah pernyataan dalam addTwoNumbers() kembali ke pengujian yang benar dan jalankan pengujian lagi agar berhasil.
  5. Dalam menu tarik turun run configurations, pilih app untuk menjalankan aplikasi Anda dengan normal.

Tugas 2. Menambahkan lebih banyak pengujian unit ke CalculatorTest

Dengan pengujian unit, Anda mengambil sedikit kode dalam aplikasi seperti metode atau kelas, dan mengisolasinya dari aplikasi, agar pengujian yang ditulis memastikan sedikit kode bekerja dengan semestinya. Biasanya pengujian unit memanggil metode dengan berbagai input yang berbeda, dan memverifikasi bahwa metode tertentu melakukan apa yang Anda harapkan dan menghasilkan apa yang Anda inginkan.

Dalam tugas ini Anda akan mempelajari lebih lanjut mengenai cara membangun pengujian unit. Anda akan menulis pengujian unit tambahan untuk metode dalam metode utilitas Kalkulator pada aplikasi SimpleCalc, dan menjalankan pengujian tersebut untuk memastikan pengujian menghasilkan keluaran yang diinginkan.

Catatan:Pengujian unit, development yang didorong pengujian, serta API JUnit 4 adalah topik yang besar dan kompleks dan berada di luar lingkup kursus ini. Lihat Resources untuk mendapatkan tautan ke informasi selengkapnya.

2.1 Menambahkan lebih banyak pengujian untuk metode add()

Walaupun tidak mungkin menguji setiap nilai yang mungkin, yang pernah dilihat metode add(), sebaiknya uji input yang mungkin tidak biasa. Misalnya, pertimbangkan apa yang terjadi jika metode add() mendapatkan argumen:

  • Dengan operand negatif.
  • Dengan angka titik-mengambang.
  • Dengan angka yang sangat besar.
  • Dengan operand tipe yang berbeda (yang mengambang dan ganda, misalnya)
  • Dengan operand yang nol.
  • Dengan operand yang tak terhingga.

Dalam tugas ini, kita akan menambahkan lebih banyak pengujian unit untuk metode add(), untuk menguji berbagai macam input yang berbeda.

  1. Menambahkan metode baru CalculatorTest bernama addTwoNumbersNegative(). Gunakan kerangka ini:

    @Test
    public void addTwoNumbersNegative() {
    }
    

    Metode ini memiliki struktur yang serupa dengan addTwoNumbers: ini adalah metode publik, tanpa parameter, yang mengembalikan kosong. Ini dianotasi dengan @Test, yang menunjukkan pengujian unit tunggal.

    Mengapa tidak menambahkan lebih banyak pernyataan ke addTwoNumbers? Mengelompokkan lebih dari satu pernyataan ke dalam satu metode tunggal dapat membuat pengujian lebih sulit di-debug jika salah satu pernyataan gagal, dan mengaburkan tes yang berhasil. Peraturan umum untuk pengujian unit adalah menyediakan metode pengujian untuk setiap pernyataan individual.

  2. Menjalankan semua pengujian di CalculatorTests, seperti sebelumnya.

    Dalam jendela pengujian, addTwoNumbers dan addTwoNumbersNegative dicantumkan sebagai tersedia (dan lulus) pengujian pada panel kiri. Pengujian addTwoNumbersNegative akan tetap lulus meskipun tidak berisi kode apa pun, pengujian yang tidak melakukan apa pun dianggap berhasil.

  3. Menambahkan baris untuk memanggil metode add() dalam kelas Kalkulator dengan operand negatif.

    double resultAdd = mCalculator.add(-1d, 2d);
    

    Notasi "d" setelah setiap operand menunjukkan bahwa ini adalah angka tipe double. Karena metode add() didefinisikan dengan parameter ganda, floats atau ints juga akan berfungsi. Menunjukkan tipe secara eksplisit memungkinkan Anda untuk menguji tipe lain secara terpisah, jika perlu.

  4. Menambahkan pernyataan dengan assertThat().

    assertThat(resultAdd, is(equalTo(1d)));
    

    Metode assertThat() adalah pernyataan JUnit4 yang mengklaim bahwa ekspresi dalam argumen pertama sama dengan yang ada dalam argumen kedua. JUnit yang lebih lama menggunakan metode pernyataan yang lebih spesifik (assertEquals(), assertNull(), assertTrue()), tetapi assertThat() adalah metode yang lebih fleksibel, mudah di-debug, dan sering kali lebih mudah untuk membaca format.

    Metode assertThat() digunakan dengan matcher. Matcher adalah panggilan metode berantai dalam operand kedua pernyataan ini (is(equalto()). Matcher yang tersedia, yang bisa Anda gunakan untuk membuat pernyataan, didefinisikan oleh framework hamcrest (Hamcrest adalah anagram untuk matcher.) Hamcrest menyediakan matcher dasar untuk pernyataan dasar. Anda juga bisa mendefinisikan matcher khusus untuk pernyataan yang lebih kompleks.

    Dalam hal ini, pernyataan adalah hasil dari operasi add() (-1 + 2) sama dengan 1.

  5. Menambahkan pengujian unit baru ke CalculatorTest untuk angka titik-mengambang:

    @Test
    public void addTwoNumbersFloats() {
       double resultAdd = mCalculator.add(1.111f, 1.111d);
       assertThat(resultAdd, is(equalTo(2.222d)));
    }
    

    Lagi, pengujian yang sangat serupa dengan metode pengujian sebelumnya, tetapi dengan satu argumen untuk ditambahkan() yang secara eksplisit adalah tipe float, bukan double. Metode add() didefinisikan dengan parameter tipe double, sehingga Anda dapat memanggilnya dengan tipe float, dan angka tersebut dipromosikan ke double.

  6. Menjalankan semua pengujian di CalculatorTests, seperti sebelumnya.
  7. Klik Run Ikon Run untuk menjalankan semua pengujian lagi.

    Kali ini pengujiannya gagal dan bilah kemajuannya berwarna merah. Ini adalah bagian penting dari pesan kesalahan:

    java.lang.AssertionError:
    Expected: is <2.222>
         but: was <2.2219999418258665>
    

    Aritmetika dengan angka titik-mengambang tidak eksak, dan promosi menghasilkan efek samping presisi tambahan. Pernyataan dalam pengujian itu secara teknis salah: nilai yang diharapkan tidak sama dengan nilai yang sebenarnya.

    Pertanyaannya adalah: saat Anda memiliki masalah presisi dengan argumen float promosi, apakah itu masalah dengan kode, atau masalah dengan pengujian? Dalam hal ini, kedua ke argumen input ke metode add() dari aplikasi Calculator selalu tipe double, sehingga pengujian ini bersifat arbitrer dan tidak realistis. Namun, jika aplikasi ditulis sedemikian rupa sehingga input ke metode add() bisa berupa double atau float dan Anda hanya peduli dengan beberapa presisi, Anda perlu menyediakan ruang toleransi pada pengujian agar "cukup dekat" diperhitungkan sebagai berhasil.

  8. Mengubah metode assertThat() untuk menggunakan matcher closeTo():

    assertThat(resultAdd, is(closeTo(2.222, 0.01)));
    

    Untuk pengujian ini, daripada menguji persamaan eksak, Anda bisa menguji persamaan dalam delta yang spesifik. Dalam hal ini, metode matcher closeTo() memerlukan dua argumen: nilai yang diharapkan dan jumlah delta. Di sini, delta itu hanya dua poin desimal presisi.

2.2 Menambahkan pengujian unit untuk metode penghitungan lain

Gunakan yang Anda pelajari dalam tugas sebelumnya untuk mengisi pengujian unit untuk kelas Kalkulator.

  1. Tambahkan pengujian unit bernama subTwoNumbers() yang menguji metode sub().
  2. Tambahkan pengujian unit bernama subWorksWithNegativeResults() yang menguji metode sub() tempat penghitungan yang diberikan menghasilkan angka yang negatif.
  3. Tambahkan pengujian unit bernama mulTwoNumbers() yang menguji metode mul().
  4. Tambahkan pengujian unit bernama mulTwoNumbersZero() yang menguji metode mul dengan sedikitnya satu argumen yang nol.
  5. Tambahkan pengujian unit bernama divTwoNumbers() yang menguji metode div() dengan dua argumen bukan nol.

Tantangan: Tambahkan pengujian unit bernama divByZero() yang menguji metode div() dengan dua argumen 0. Petunjuk: Coba ini dalam aplikasi terlebih dulu untuk melihat hasilnya.

Kode Solusi:

@Test
public void addTwoNumbers() {
   double resultAdd = mCalculator.add(1d, 1d);
   assertThat(resultAdd, is(equalTo(2d)));
}

@Test
public void addTwoNumbersNegative() {
   double resultAdd = mCalculator.add(-1d, 2d);
   assertThat(resultAdd, is(equalTo(1d)));
}
@Test
public void addTwoNumbersFloats() {
   double resultAdd = mCalculator.add(1.111f, 1.111d);
assertThat(resultAdd, is(closeTo(2.222, 0.01)));
}
@Test
public void subTwoNumbers() {
   double resultSub = mCalculator.sub(1d, 1d);
   assertThat(resultSub, is(equalTo(0d)));
}
@Test
public void subWorksWithNegativeResult() {
   double resultSub = mCalculator.sub(1d, 17d);
   assertThat(resultSub, is(equalTo(-16d)));
}
@Test
public void mulTwoNumbers() {
   double resultMul = mCalculator.mul(32d, 2d);
   assertThat(resultMul, is(equalTo(64d)));
}
@Test
public void divTwoNumbers() {
   double resultDiv = mCalculator.div(32d,2d);
   assertThat(resultDiv, is(equalTo(16d)));
}
@Test
public void divTwoNumbersZero() {
   double resultDiv = mCalculator.div(32d,0);
   assertThat(resultDiv, is(equalTo(Double.POSITIVE_INFINITY)));
}

Kode Solusi

Proyek Android Studio: Pengujian SimpleCalc

Tantangan penyusunan kode

Catatan: Semua tantangan penyusunan kode opsional dan bukan prasyarat untuk pelajaran berikutnya.

Tantangan 1: Membagi dengan nol selalu pantas diujikan, karena itu adalah kasus spesial dalam aritmetika. Jika Anda mencoba membagi dengan nol dalam versi terbaru aplikasi SimpleCalc, aplikasi akan berperilaku seperti yang didefinisikan Java: Membagi angka dengan akan mengembalikan konstanta "Infinity" (Double.POSITIVE_INFINITY). Membagi 0 dengan 0 menghasilkan konstanta bukan angka (Double.nan). Walaupun nilai ini benar untuk Java, nilai-nilai ini bukan berarti nilai yang berguna untuk pengguna dalam aplikasi itu sendiri. Bagaimana Anda mengubah aplikasi untuk lebih baik dalam menangani dibagi dengan nol? Untuk menyelesaikan tantangan ini, pertama mulailah dengan pengujian -- pertimbangkan perilaku apa yang benar, lalu tulis pengujian seakan-akan perilaku tersebut sudah ada. Lalu ubah atau tambahkan kode agar pengujian muncul berwarna hijau.

Tantangan 2: Kadang-kadang sulit mengisolasi unit kode dari semua dependensi eksternalnya. Daripada mengelola kode secara artifisial dengan cara yang rumit hanya supaya dapat diuji dengan lebih mudah, Anda bisa menggunakan framework palsu untuk membuat objek tiruan yang berpura-pura menjadi dependensi. Pelajari framework Mockito, dan pelajari cara menyiapkannya di Android Studio. Tulis kelas pengujian untuk metode calcButton() dalam SimpleCalc, dan gunakan Mockito untuk menyimulasi konteks Android tempat pengujian akan dijalankan.

Rangkuman

  • Android Studio memiliki fitur bawaan untuk pengujian unit lokal.
    • Pengujian unit lokal menggunakan JVM mesin lokal dan tidak menggunakan framework Android.
    • Pengujian unit ditulis dengan JUnit, framework pengujian unit yang umum untuk Java.
    • Folder "pengujian" (Tampilan Proyek Android Studio) adalah tempat di mana pengujian JUnit berada.
    • Pengujian unit lokal hanya memerlukan paket: org.junit, org.hamcrest dan android.test
    • Anotasi @RunWith(JUnit4.class) memerintahkan runner pengujian untuk menjalankan pengujian dalam kelas ini.
    • Anotasi @SmallTest, @MediumTest, dan @LargeTest adalah konvensi yang memudahkan membundel grup pengujian yang serupa.
    • Anotasi @SmallTest menunjukkan bahwa semua pengujian dalam kelas adalah pengujian unit yang tidak memiliki dependensi dan berjalan dalam milidetik.
  • Pengujian berinstrumen adalah pengujian yang bekerja pada perangkat Android atau emulator.
    • Pengujian berinstrumen memiliki akses ke framework Android.
  • Runner pengujian adalah pustaka atau serangkaian alat yang memungkinkan pengujian terjadi dan hasilnya dicetak ke log.

Konsep terkait

Dokumentasi konsep terkait ada di Dasar-Dasar Developer Android: Konsep.

Ketahui Selengkapnya

results matching ""

    No results matching ""