Resource nonaktif Espresso

Resource nonaktif mewakili operasi asinkron yang hasilnya memengaruhi operasi berikutnya dalam pengujian UI. Dengan mendaftarkan resource nonaktif ke Espresso, Anda dapat memvalidasi operasi asinkron ini dengan lebih andal saat menguji aplikasi.

Mengidentifikasi kapan resource nonaktif diperlukan

Espresso memberikan serangkaian kemampuan sinkronisasi yang canggih. Namun, karakteristik framework ini hanya berlaku untuk operasi yang memposting pesan di MessageQueue, seperti subclass View yang menggambar kontennya di layar.

Karena Espresso tidak mengetahui operasi asinkron lainnya, termasuk yang berjalan di thread latar belakang, Espresso tidak dapat memberikan jaminan sinkronisasi dalam situasi tersebut. Agar Espresso mengetahui operasi aplikasi yang berjalan lama, Anda harus mendaftarkan masing-masing operasi sebagai resource nonaktif.

Jika tidak menggunakan resource nonaktif saat menguji hasil tugas asinkron aplikasi, Anda mungkin harus menggunakan salah satu solusi buruk berikut untuk meningkatkan keandalan pengujian:

  • Menambahkan panggilan ke Thread.sleep(). Saat Anda menambahkan penundaan buatan ke pengujian, rangkaian pengujian akan membutuhkan waktu lebih lama untuk menyelesaikan eksekusi, dan pengujian mungkin masih gagal saat dijalankan di perangkat yang lebih lambat. Selain itu, penundaan ini tidak diskalakan dengan baik, karena aplikasi Anda mungkin harus melakukan pekerjaan asinkron yang lebih memakan waktu dalam rilis mendatang.
  • Mengimplementasikan wrapper coba lagi, yang menggunakan loop untuk memeriksa berulang kali apakah aplikasi masih menjalankan pekerjaan asinkron hingga waktu tunggu habis. Meskipun Anda menentukan jumlah percobaan ulang maksimum dalam pengujian, setiap eksekusi ulang akan menggunakan resource sistem, terutama CPU.
  • Menggunakan instance CountDownLatch, yang memungkinkan satu atau beberapa thread menunggu hingga sejumlah operasi tertentu yang dijalankan di thread lainnya selesai. Objek-objek ini mengharuskan Anda menentukan durasi waktu tunggu; jika tidak, aplikasi Anda mungkin akan diblokir tanpa batas. Kait tersebut juga menambahkan kompleksitas yang tidak perlu pada kode Anda, sehingga pemeliharaan akan menjadi lebih sulit.

Dengan Espresso, Anda dapat menghapus solusi yang tidak dapat diandalkan ini dari pengujian dan mendaftarkan pekerjaan asinkron aplikasi sebagai resource nonaktif.

Kasus penggunaan umum

Saat menjalankan operasi yang mirip dengan contoh berikut dalam pengujian, sebaiknya gunakan resource nonaktif:

  • Memuat data dari internet atau sumber data lokal.
  • Membuat koneksi dengan database dan callback.
  • Mengelola layanan, menggunakan layanan sistem atau instance IntentService.
  • Menjalankan logika bisnis yang kompleks, seperti transformasi bitmap.

Sangat penting untuk mendaftarkan resource nonaktif saat operasi ini mengupdate UI yang kemudian divalidasi oleh pengujian Anda.

Contoh implementasi resource nonaktif

Daftar berikut menjelaskan beberapa contoh implementasi resource nonaktif yang dapat Anda integrasikan ke dalam aplikasi:

CountingIdlingResource
Mempertahankan penghitung tugas aktif. Jika penghitung bernilai nol, resource terkait dianggap tidak ada aktivitas. Fungsionalitas ini sangat mirip dengan Semaphore. Pada umumnya, implementasi ini cukup untuk mengelola tugas asinkron aplikasi selama pengujian.
UriIdlingResource
Mirip dengan CountingIdlingResource, tetapi penghitung harus nol selama periode waktu tertentu sebelum resource dianggap tidak ada aktivitas. Periode tunggu tambahan ini mempertimbangkan permintaan jaringan berturut-turut, saat aplikasi di thread Anda dapat membuat permintaan baru segera setelah menerima respons terhadap permintaan sebelumnya.
IdlingThreadPoolExecutor
Implementasi kustom ThreadPoolExecutor yang melacak jumlah total tugas yang berjalan dalam kumpulan thread yang dibuat. Class ini menggunakan CountingIdlingResource untuk mempertahankan penghitung tugas aktif.
IdlingScheduledThreadPoolExecutor
Implementasi kustom ScheduledThreadPoolExecutor. Class ini menyediakan fungsionalitas dan kemampuan yang sama dengan class IdlingThreadPoolExecutor, tetapi juga dapat melacak tugas yang dijadwalkan untuk masa mendatang atau dijadwalkan untuk dijalankan secara berkala.

Membuat resource nonaktif sendiri

Saat menggunakan resource nonaktif dalam pengujian aplikasi, Anda mungkin perlu menyediakan logging atau pengelolaan resource kustom. Dalam kasus tersebut, implementasi yang tercantum di bagian sebelumnya mungkin tidak cukup. Jika demikian, Anda dapat memperluas salah satu implementasi resource nonaktif ini atau membuatnya sendiri.

Jika Anda mengimplementasikan fungsi resource nonaktif Anda sendiri, ingat praktik terbaik berikut, terutama yang pertama:

Panggil transisi ke status nonaktif di luar pemeriksaan nonaktif.
Setelah aplikasi Anda tidak ada aktivitas, panggil onTransitionToIdle() di luar implementasi isIdleNow(). Dengan demikian, Espresso tidak melakukan pemeriksaan kedua yang tidak perlu untuk menentukan apakah resource nonaktif yang diberikan tidak ada aktivitas.

Cuplikan kode berikut mengilustrasikan rekomendasi ini:

Kotlin

fun isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

fun backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}

Java

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
Daftarkan resource nonaktif sebelum memerlukannya.

Manfaat sinkronisasi yang terkait dengan resource nonaktif hanya berlaku setelah pemanggilan pertama Espresso terhadap metode isIdleNow() resource tersebut.

Daftar berikut menunjukkan beberapa contoh properti ini:

  • Jika Anda mendaftarkan resource nonaktif dalam metode yang dianotasikan dengan @Before, resource nonaktif akan berlaku di baris pertama setiap pengujian.
  • Jika Anda mendaftarkan resource nonaktif di dalam pengujian, resource nonaktif akan berlaku selama tindakan berbasis Espresso berikutnya. Perilaku ini masih terjadi meskipun tindakan berikutnya berada dalam pengujian yang sama dengan pernyataan yang mendaftarkan resource tidak ada aktivitas.
Batalkan pendaftaran resource nonaktif setelah selesai menggunakannya.

Untuk menghemat resource sistem, Anda harus membatalkan pendaftaran resource nonaktif segera setelah tidak memerlukannya lagi. Misalnya, jika Anda mendaftarkan resource nonaktif dalam metode yang dianotasikan dengan @Before, sebaiknya batalkan pendaftaran resource ini dalam metode terkait yang dianotasikan dengan @After.

Gunakan registry nonaktif untuk mendaftarkan dan membatalkan pendaftaran resource nonaktif.

Dengan menggunakan penampung ini untuk resource nonaktif aplikasi, Anda dapat mendaftarkan dan membatalkan pendaftaran resource nonaktif berulang kali sesuai kebutuhan dan masih mengamati perilaku yang konsisten.

Pertahankan hanya status aplikasi sederhana dalam resource nonaktif.

Misalnya, resource nonaktif yang Anda implementasikan dan daftarkan tidak boleh berisi referensi ke objek View.

Mendaftarkan resource nonaktif

Espresso menyediakan class container tempat Anda dapat menempatkan resource nonaktif aplikasi. Class ini, yang disebut IdlingRegistry, adalah artefak mandiri yang memperkenalkan overhead minimal ke aplikasi Anda. Class ini juga memungkinkan Anda mengambil langkah-langkah berikut untuk meningkatkan pengelolaan aplikasi:

  • Buat referensi ke IdlingRegistry, bukan ke resource nonaktif yang dimuatnya, di pengujian aplikasi Anda.
  • Mempertahankan perbedaan dalam kumpulan resource nonaktif yang Anda gunakan untuk setiap varian build.
  • Tentukan resource nonaktif di layanan aplikasi Anda, bukan di komponen UI yang mereferensikan layanan tersebut.

Mengintegrasikan resource nonaktif ke dalam aplikasi

Meskipun Anda dapat menambahkan resource nonaktif ke aplikasi dengan beberapa cara, satu pendekatan secara khusus dapat mempertahankan enkapsulasi untuk aplikasi Anda sekaligus tetap memungkinkan Anda menentukan operasi tertentu yang diwakili oleh resource nonaktif tertentu.

Saat menambahkan resource nonaktif ke aplikasi, kami sangat merekomendasikan untuk menempatkan logika resource nonaktif di aplikasi itu sendiri, dan hanya lakukan operasi pendaftaran dan pembatalan pendaftaran dalam pengujian Anda.

Meskipun membuat situasi yang tidak biasa dengan menggunakan antarmuka khusus pengujian dalam kode produksi dengan mengikuti pendekatan ini, Anda dapat menggabungkan resource nonaktif pada kode yang sudah dimiliki untuk mempertahankan ukuran APK dan jumlah metode aplikasi.

Pendekatan alternatif

Jika memilih untuk tidak memiliki logika resource nonaktif dalam kode produksi aplikasi, ada beberapa strategi integrasi lain yang dapat dilakukan:

  • Buat varian build, seperti ragam produk Gradle, dan gunakan resource nonaktif hanya dalam build debug aplikasi.
  • Gunakan framework injeksi dependensi seperti Dagger untuk memasukkan grafik dependensi resource nonaktif aplikasi ke dalam pengujian Anda. Jika Anda menggunakan Dagger 2, injeksi itu sendiri harus berasal dari subkomponen.
  • Implementasikan resource nonaktif dalam pengujian aplikasi, dan tampilkan bagian implementasi aplikasi yang perlu disinkronkan dalam pengujian tersebut.

    Perhatian: Meskipun tampaknya membuat referensi mandiri untuk resource nonaktif, keputusan desain ini juga memecah enkapsulasi di semua aplikasi kecuali di aplikasi yang paling sederhana.

Referensi lainnya

Untuk mengetahui informasi selengkapnya tentang penggunaan Espresso dalam pengujian Android, lihat referensi berikut.

Contoh