Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Menguji Antarmuka Pengguna Android Dengan Espresso

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Imam Firmansyah (you can also view the original English article)

Dalam postingan ini, Anda akan belajar tentang bagaimana menulis tes UI dengan framwework pengujian Espresso dan mengotomatisasi alur kerja pengujian Anda, daripada menggunakan proses manual yang sangat rawan kesalahannya.

Espresso adalah framework pengujian untuk menulis tes UI di Android. Menurut dokumen resminya, Anda dapat:

Gunakan Espresso untuk menulis tes UI Android yang ringkas, indah, dan andal.

1. Mengapa Menggunakan Espresso?

Salah satu masalah dengan pengujian manual adalah dapat memakan waktu dan membosankan untuk dilakukan. Misalnya, untuk menguji tampilan login (secara manual) di aplikasi Android, Anda harus melakukan hal berikut:

  1. Jalankan aplikasi.
  2. Arahkan ke layar login.
  3. Konfirmasi apakah usernameEditText dan passwordEditText terlihat.
  4. Ketikkan username dan password ke dalam kolomnya masing-masing.
  5. Konfirmasi apakah tombol login juga terlihat, lalu klik tombol login tersebut.
  6. Periksa apakah tampilan yang benar ditampilkan ketika proses login berhasil atau gagal.

Daripada menghabiskan waktu, secara manual menguji aplikasi kita akan lebih baik untuk menghabiskan lebih banyak waktu menulis kode yang membuat aplikasi kita menonjol dari yang lain! Dan, meskipun pengujian manual membosankan dan cukup lambat, itu masih rawan kesalahannya dan Anda mungkin melewatkan beberapa kasus pojok.

Beberapa keuntungan dari pengujian otomatis adalah sebagai berikut:

  • Tes otomatis mengeksekusi kasus uji yang sama setiap kali mereka dieksekusi.
  • Developer dapat dengan cepat menemukan masalah dengan cepat sebelum dikirim ke tim QA.
  • Dapat menghemat banyak waktu, tidak seperti melakukan pengujian manual. Dengan menghemat waktu, software engineer dan tim QA malah dapat menghabiskan lebih banyak waktu untuk tugas yang menantang dan bermanfaat.
  • Cakupan uji yang lebih tinggi tercapai, yang mengarah ke aplikasi kualitas yang lebih baik.

Dalam tutorial ini, kita akan belajar tentang Espresso dengan mengintegrasikannya ke dalam proyek Android Studio. Kita akan menulis tes UI untuk layar login dan RecyclerView, dan kita akan belajar tentang pengujian.

Kualitas bukanlah suatu tindakan, itu adalah kebiasaan. -Pablo Picasso

2. Prasayarat

Untuk dapat mengikuti tutorial ini, Anda akan membutuhkan:

Contoh proyek (di Kotlin) untuk tutorial ini dapat ditemukan di repo GitHub kami sehingga Anda dapat dengan mudah mengikutinya.

3. Buat Android Studio Project

Jalankan Android Studio 3 Anda dan buat project baru dengan activity kosong bernama MainActivity. Pastikan untuk memeriksa Include Kotlin support.

Create Android Project dialog

4. Mengatur Espresso dan AndroidJUnitRunner

Setelah membuat new project, pastikan untuk menambahkan dependensi berikut dari Android Testing Support Library di build.gradle (meskipun Android Studio sudah menyertakannya untuk kita). Dalam tutorial ini, kita gunakan versi terbaru library Espresso 3.0.2 (seperti pada tulisan berikut).

Kita juga menyertakan runner instrumentasi AndroidJUnitRunner:

Sebuah Instrumentation yang menjalankan tes JUnit3 dan JUnit4 terhadap paket Android (aplikasi).

Perhatikan bahwaInstrumentation hanyalah sebuah kelas dasar untuk mengimplementasikan kode instrumentasi aplikasi.

Matikan Animasi

Sinkronisasi Espresso, yang tidak tahu bagaimana menunggu animasi selesai, dapat menyebabkan beberapa tes gagal — jika Anda mengizinkan animasi pada perangkat tes Anda. Untuk mematikan animasi pada perangkat uji Anda, buka Settings > Developer Optionsdan matikan semua opsi berikut di bawah bagian "Drawing":

  • Window animation scale
  • Transition animation scale
  • Animator duration scale

5. Tulis Pengujian Pertama Anda di Espresso

Pertama, kita mulai menguji layar Login. Beginilah alur login bekerja: pengguna meluncurkan aplikasi, dan layar pertama yang ditampilkan berisi satu tombol Login. Ketika tombol Login diklik, maka akan membuka layar LoginActivity. Layar ini hanya berisi dua EditText(username dan password) dan tombol Submit.

Inilah tampilan layout MainActivity:

MainActivity layout

Ini tampilan layout LoginActivity:

Sekarang kita tulis untuk class MainActivity. Buka class MainActivityAnda, gerakan kursor ke nama MainActivity, dan tekan Shift-Control-T. Pilih Create New Test... di menu popup.

Create new test dialog

Tekan tombol OK, dan dialog lain muncul. Pilih direktori androidTestdan klik tombol OK sekali lagi. Perhatikan bahwa karena kita menulis uji instrumentasi (tes khusus Android SDK), kasus uji berada di folder androidTest/java.

Sekarang, Android Studio telah berhasil membuat class tes untuk kita. Di atas nama kelas, sertakan anotasi ini: @RunWith(AndroidJUnit4::class).

Anotasi ini menandakan bahwa semua tes di kelas ini adalah tes khusus Android.

Testing Activities

Karena kita ingin menguji suatu Activity, kita harus melakukan sedikit pengaturan. Kita perlu memberi tahu Espresso Activity mana yang dibuka atau dijalankan sebelum mengeksekusi dan menghancurkan setelah menjalankan metode uji apa pun.

Perhatikan bahwa anotasi @Rule berarti ini adalah aturan pengujian JUnit4. Aturan pengujian JUnit4 dijalankan sebelum dan sesudah setiap metode pengujian (dianotasikan dengan @Test). Dalam skenario kita, kita akan menjalankanMainActivity sebelum setiap metode pengujian dan setelah itu menghapusnya.

Kami juga menyertakan anotasi @JvmField Kotlin. Ini hanya menginstruksikan compiler untuk tidak menghasilkan getter dan setter untuk properti dan sebagai gantinya untuk mengeksposnya sebagai bidang Java sederhana.

Berikut adalah tiga langkah utama dalam menulis tes Espresso:

  • Cari widget (misalnya TextView atau Button) yang ingin Anda uji.
  • Lakukan satu atau beberapa tindakan di widget tersebut.
  • Verifikasi atau periksa untuk melihat apakah widget tersebut sekarang dalam keadaan pasti.

Jenis anotasi berikut dapat diterapkan ke metode yang digunakan di dalam class pengujian.

  • @BeforeClass: menunjukkan bahwa metode statis anotasi ini diterapkan untuk harus dijalankan sekali dan sebelum semua tes di dalam kelas. Ini bisa digunakan untuk, misalnya, mengatur koneksi ke database.
  • @Before: menunjukkan bahwa metode anotasi ini dilampirkan untuk harus dijalankan sebelum setiap metode tes di dalam class.
  • @Test: menunjukkan bahwa metode anotasi ini dilampirkan untuk dijalankan sebagai kasus pengujian.
  • @After: menunjukkan bahwa metode anotasi ini dilampirkan untuk dijalankan setelah setiap metode pengujian.
  • @AfterClass: menunjukkan bahwa metode anotasi ini dilampirkan untuk dijalankan setelah semua metode pengujian di dalam class telah dijalankan. Di sini, kita biasanya menutup sumber daya yang dibuka di @BeforeClass.

Temukan ViewMenggunakanonView()

Dalam file layout MainActivity, kita hanya mempunyai satu widget tombol Login. Mari kita uji skenario di mana pengguna akan menemukan tombol tersebut dan mengkliknya.

Untuk menemukan widget di Espresso, kita menggunakan metode statis onView() (buka findViewById()). Jenis parameter yang kita berikan ke onView() adalah Matcher. Perhatikan bahwa API Matcher tidak berasal dari SDK Android tetapi dari Hamcrest Project. Library Hamcrest's matcher ada di dalam library Espresso yang kami tarik melalui Gradle.

onView(withId(R.id.btn_login)) akan mengembalikan ViewInteraction yang merupakan View yang ID-nya adalah R.id.btn_login. Pada contoh di atas, kita menggunakan withId()untuk mencari widget dengan id yang diberikan. View matcher lain yang bisa kita gunakan adalah:

  • withText(): engembalikan matcher yang cocok dengan TextView berdasarkan nilai properti teksnya.
  • withHint(): mengembalikan matcher yang cocok dengan TextView berdasarkan pada nilai isi propertinya.
  • withTagKey(): mengembalikan matcher yang cocok denganView berdasarkan kunci tag.
  • withTagValue(): mengembalikan matcher yang cocok dengan View berdasarkan nilai properti tag.

Pertama, mari kita uji untuk melihat apakah tombol tersebut benar-benar ditampilkan di layar.

Di sini, kami hanya mengkonfirmasikan jika tombol dengan id yang diberikan (R.id.btn_login) terlihat oleh pengguna, jadi kami menggunakan metode check() untuk mengonfirmasi apakah Viewyang mendasari memiliki keadaan tertentu — dalam kasus ini, jika itu terlihat.

Metode statis matches() mengembalikan ViewAssertion generik yang menegaskan bahwa bview yang ada dalam hierarki view dan dicocokkan dengan view matcher yang diberikan. Bahwa peninjau tampilan yang diberikan dikembalikan oleh panggilan isDisplayed(). Seperti yang disarankan oleh nama metode, isDisplayed() adalah matcher yang yang cocok dengan View yang sedang ditampilkan pada layar untuk pengguna. Sebagai contoh, jika kita ingin memeriksa apakah tombol diaktifkan, kita cukup melewati isEnabled() untuk matches().

View matcher populer lainnya yang dapat kita lewati ke dalam metodematches() adalah:

  • hasFocus(): mengembalikan matcher yang cocok dengan View yang saat ini memiliki fokus.
  • isChecked(): mengembalikan matcher yang menerima jika dan hanya jika view nya adalah CompoundButton (atau subtipe) dan dalam keadaaan dicentang. Kebalikan dari metode ini adalah isNotChecked().
  • isSelected(): mengembalikan matcher yang cocok dengan View yang dipilih.

Untuk menjalankan pengujian, Anda dapat mengeklik segitiga hijau di samping metode atau nama class. Mengklik segitiga hijau di samping nama kelas akan menjalankan semua metode pengujian di class tersebut, sedangkan yang di sebelah metode akan menjalankan pengujian hanya untuk metode itu.

MainActivityTest class

Hore! Pengujian telah kita lalui!

Android Studio test result toolbar

Lakukan Action pada View

Pada objek ViewInteraction yang dikembalikan dengan memanggil onView(), kita dapat mensimulasikan tindakan yang dapat dilakukan pengguna di widget. Sebagai contoh, kita dapat mensimulasikan aksi klik dengan hanya memanggil metode statis click() di dalam class ViewActions. Ini akan mengembalikan objek ViewAction untuk kita.

Dokumentasinya mengatakan bahwa ViewAction-nya adalah:

Bertanggung jawab untuk melakukan interaksi pada elemen View yang diberikan.

Kami melakukan event klik dengan melakukan pemanggilan pertama perform(). Metode ini melakukan tindakan yang diberikan pada view yang dipilih oleh view matcher saat ini. Perhatikan bahwa kita dapat meneruskannya satu tindakan atau daftar tindakan (dieksekusi secara berurutan). Di sini, kita memberikannya click(). Tindakan lain yang mungkin dilakukan adalah:

  • typeText() untuk meniru mengetik teks ke dalam EditText.
  • clearText() untuk mensimulasikan kliring teks dalam EditText.
  • doubleClick() untuk mensimulasikan klik ganda pada View.
  • longClick() untuk meniru long-click pada View.
  • scrollTo() untuk mensimulasikan scrolling ScrollView ke View tertentu yang terlihat.
  • swipeLeft() untuk mensimulasikan swiping kanan ke kiri melintasi pusat vertikal View.

Masih banyak lagi simulasi dapat ditemukan di dalam class ViewActions.

Memnvalidasi dengan View Assertions

Mari selesaikan pengujian kita, untuk memvalidasi bahwa layar LoginActivity ditampilkan setiap kali tombol Login diklik. Meskipun kita telah melihat bagaimana menggunakan check() pada ViewInteraction, mari kita gunakan lagi, lalu memberinya ViewAssertion yang lain.

Di dalam file layout LoginActivity, selain dari EditText dan Button, kita juga punya TextView dengan ID R.id.tv_login. Jadi kami hanya melakukan pemeriksaan untuk mengonfirmasi bahwa TextView telihat oleh pengguna.

Sekarang Anda dapat menjalankan pengujian lagi!

Android Studio test result toolbar

Tes Anda akan berhasil jika Anda mengikuti semua langkah dengan benar.

Inilah yang terjadi selama proses pelaksanaan pengujian kita:

  1. Jalankan MainActivity menggunakan field activityRule.
  2. Terverifikasi jika tombol Login (R.id.btn_login) terlihat (isDisplayed()) kepada pengguna.
  3. Simulasikan aksi klik (click()) pada tombol tersebut.
  4. Terverifikasi jika LoginActivity ditunjukkan kepada pengguna dengan memeriksa apakah TextView dengan id R.id.tv_logindi LoginActivity terlihat.

Anda dapat merujuk ke Espresso cheat sheet untuk melihat variasi view matchers, view actions, and view assertions yang tersedia.

6. Uji Layar LoginActivity

Berikut LoginActivity.kt kita:

Dalam kode di atas, jika username yang dimasukkan adalah "chike" dan passwordnya adalah "password", maka proses login berhasil. Untuk masukan lainnya, itu gagal. Mari sekarang menulis pengujian Espresso untuk ini!

Buka LoginActivity.kt, pindahkan kursor ke nama LoginActivity, dan tekan Shift-Control-T. Pilih Create New Test... di menu popup. Ikuti proses yang sama seperti yang kita lakukan untuk MainActivity.kt, dan klik tombol OK.

Class pengujian ini sangat mirip dengan yang pertama. Jika kita jalankan pengujian, layar LoginActivity terbuka. Username dan password diketikkan ke kolom R.id.et_username dan R.id.et_password. Selanjutnya, Espresso akan mengklik tombol Submit (R.id.btn_submit). Ini akan menunggu sampai View dengan id R.id.tv_login dapat ditemukan dengan teks yang berbunyi Success.

7. Uji RecyclerView

RecyclerViewActions adalah class yang mengekspos satu set API untuk beroperasi pada RecyclerView. RecyclerViewActions adalah bagian dari artefak yang terpisah di dalam artefak espresso-contrib, yang juga harus ditambahkan ke build.gradle:

Perhatikan bahwa artefak ini juga berisi API untuk UI yang menguji panel samping navigasi melalui DrawerActions dan DrawerMatchers.

Untuk mengklik suatu item pada posisi apa pun dalam RecyclerView, kita akan mengaktifkan actionOnItemAtPosition(). Kami harus memberikannya sebuah jenis barang. Dalam kasus ini, itemnya adalah class ViewHolder di dalam RandomAdapter. Metode ini juga membutuhkan dua parameter; yang pertama adalah posisi, dan yang kedua adalah tindakan (ViewActions.click()).

RecyclerViewActions lainnya yang dapat dilakukan adalah:

  • actionOnHolderItem(): melakukan ViewAction pada view yang dicocokkan oleh viewHolderMatcher. Ini memungkinkan kita untuk mencocokkannya dengan apa yang ada di dalam ViewHolder daripada posisi.
  • scrollToPosition(): mengembalikan ViewAction yang men-scroll RecyclerView ke posisi.

Berikutnya (setelah "add note screen" terbuka), kita akan memasukkan teks catatan kita dan menyimpan catatannya. Kita tidak perlu menunggu layar baru terbuka — Espresso akan melakukannya secara otomatis untuk kita. Ini menunggu sampai View dengan id R.id.add_note_title dapat ditemukan.

8. Uji Intent

Espresso menggunakan artefak lain bernama espresso-intents untuk pengujian intents. Artefak ini hanyalah perpanjangan lain untuk Espresso yang berfokus pada validasi dan mocking Intents. Mari kita lihat contohnya.

Pertama, kita harus menarik library espresso-intents ke dalam proyek kita.

IntentsTestRule memperluas ActivityTestRule, sehingga keduanya memiliki perilaku serupa. Inilah yang dikatakan oleh dokumentasi:

Kelas ini merupakan perpanjangan dari ActivityTestRule, yang menginisialisasi Espresso-Intents sebelum setiap pengujian yang dianotasikan dengan Test dan merilis Espresso-Intents setelah setiap uji coba dijalankan. Aktivitas akan dihentikan setelah setiap pengujian dan aturan ini dapat digunakan dengan cara yang sama dengan ActivityTestRule.

Fitur pembeda utama adalah bahwa ia memiliki fungsionalitas tambahan untuk menguji startActivity() dan startActivityForResult() dengan mocks dan stubs.

Kita sekarang akan menguji skenario di mana pengguna akan mengklik tombol (R.id.btn_select_contact) pada layar untuk memilih kontak dari daftar kontak telepon.

Di sini kita menggunakan intending() dari library espresso-intents untuk membuat stub dengan tanggapan tiruan untuk permintaan ACTION_PICK. Inilah yang terjadi di PickContactActivity.kt ketika pengguna mengklik tombol dengan id R.id.btn_select_contact untuk memilih kontak.

intending() mengambil dalam Matcher yang cocok dengan maksud untuk tanggapan yang mematikan yang harus disediakan. Dengan kata lain Matcher mengidentifikasi permintaan mana yang Anda minati. Dalam kasus ini, kita menggunakan hasAction() (metode helper di IntentMatchers) untuk menemukan permintaan ACTION_PICK. Kita lalu memanggil respondWith(), yang menetapkan hasil untuk onActivityResult(). Dalam kasus ini, hasilnya memiliki Activity.RESULT_OK, mensimulasikan pengguna memilih kontak dari daftar.

Kita kemudian mensimulasikan mengklik tombol pilih kontak, yang memanggil startActivityForResult(). Perhatikan bahwa stub kita mengirim tanggapan tiruan ke onActivityResult().

Akhirnya, kita menggunakan metode bantuan intended() untuk memvalidasi bahwa panggilan ke startActivity() dan startActivityForResult() dibuat dengan informasi yang benar.

Kesimpulan

Dalam tutorial ini, Anda belajar cara mudah menggunakan framework pengujian Espresso di proyek Android Studio Anda untuk mengotomatiskan alur kerja pengujian Anda.

Saya sangat merekomendasikan memeriksa dokumentasi resmi untuk mempelajari lebih lanjut tentang menulis pengujian UI dengan Espresso.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.