The Android Developer Challenge is back! Submit your idea before December 2.

Resource nonaktif Espresso

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

Mengidentifikasi kapan resource nonaktif diperlukan

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

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

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

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

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

Kasus penggunaan umum

Saat menjalankan operasi yang mirip dengan contoh berikut dalam pengujian, pertimbangkan untuk menggunakan resource nonaktif:

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

Sangat penting untuk mendaftarkan resource nonaktif saat operasi tersebut mengupdate UI yang kemudian akan 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. Saat penghitung menunjukkan nol, resource yang terkait akan dianggap nonaktif. Fungsionalitas ini sangat mirip dengan Semaphore. Umumnya, implementasi ini cukup untuk mengelola pekerjaan asinkron aplikasi Anda selama pengujian.
UriIdlingResource
Mirip dengan CountingIdlingResource, tetapi penghitung harus nol selama periode waktu tertentu sebelum resource dianggap nonaktif. Periode tunggu tambahan ini mempertimbangkan permintaan jaringan berturut-turut, saat aplikasi di thread mungkin membuat permintaan baru segera setelah menerima respons terhadap permintaan sebelumnya.
IdlingThreadPoolExecutor
Implementasi kustom ThreadPoolExecutor yang melacak jumlah total tugas yang berjalan di dalam kumpulan thread yang dibuat. Class ini menggunakan CountingIdlingResource untuk mempertahankan penghitung tugas aktif.
IdlingScheduledThreadPoolExecutor
Implementasi kustom dari ScheduledThreadPoolExecutor. Dengannya, Anda mendapatkan 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 pengelolaan atau logging resource kustom. Dalam hal ini, implementasi yang tercantum di bagian sebelumnya mungkin tidak akan cukup. Jika demikian, Anda dapat memperluas salah satu dari implementasi resource nonaktif ini atau membuatnya sendiri.

Jika mengimplementasikan fungsionalitas resource nonaktif Anda sendiri, ikuti beberapa praktik terbaik berikut ini, terutama yang pertama:

Panggil transisi ke status nonaktif di luar pemeriksaan nonaktif.
Setelah aplikasi Anda tidak melakukan aktivitas, panggil onTransitionToIdle() di luar setiap implementasi isIdleNow(). Dengan begitu, Espresso tidak melakukan pemeriksaan kedua yang tidak diperlukan untuk menentukan apakah resource nonaktif yang diberikan tidak melakukan 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 dianotasi dengan @Before, resource nonaktif akan berlaku di baris pertama setiap pengujian.
  • Jika Anda mendaftarkan dalam suatu pengujian, resource nonaktif akan berlaku hingga tindakan berbasis Espresso berikutnya. Perilaku ini masih terjadi meskipun tindakan selanjutnya berada di dalam pengujian yang sama dengan pernyataan yang mendaftarkan resource nonaktif tersebut.
Batalkan pendaftaran resource nonaktif setelah selesai menggunakannya.

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

Gunakan registry nonaktif untuk mendaftarkan dan membatalkan pendaftaran resource nonaktif.

Dengan menggunakan container ini untuk resource nonaktif aplikasi, Anda dapat mendaftarkan dan membatalkan pendaftaran resource nonaktif berulang kali sesuai kebutuhan dan masih melihat 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 dan memberikan overhead minimal ke aplikasi Anda. Class ini juga memungkinkan Anda untuk mengambil langkah-langkah berikut guna meningkatkan pemeliharaan aplikasi:

  • Membuat referensi ke IdlingRegistry, bukan ke resource nonaktif di dalamnya, di pengujian aplikasi.
  • Mempertahankan perbedaan dalam kumpulan resource nonaktif yang Anda gunakan untuk setiap varian build.
  • Menetapkan resource nonaktif di layanan aplikasi Anda, bukan di komponen UI yang merujuk layanan tersebut.

Mengintegrasikan resource nonaktif ke dalam aplikasi

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

Saat menambahkan resource nonaktif ke dalam aplikasi, kami sangat merekomendasikan untuk melakukan hanya operasi pendaftaran dan membatalkan pendaftaran dalam pengujian, serta menempatkan logika resource nonaktif itu sendiri di dalam kode produksi aplikasi Anda.

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

Pendekatan alternatif

Jika lebih memilih untuk tidak memiliki logika resource nonaktif dalam kode produksi aplikasi, ada beberapa strategi integrasi yang patut Anda coba:

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

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

Referensi lainnya

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

Contoh