Kami mengotomatiskan pengujian UI aplikasi Android menggunakan pola Obyek Halaman

gambar

Pola Objek Halaman muncul dalam pengujian web dan terbukti sangat bagus di sana. Ketika saya mulai mengotomatiskan tes untuk aplikasi android, hal pertama yang saya pikirkan adalah. Saya mencari informasi di jaringan, bertanya pada kolega saya dan, pada prinsipnya, tidak menemukan alasan untuk tidak mencoba. Saya mengusulkan untuk melihat apa yang terjadi.

Objek Halaman klasik menyiratkan dua tingkat abstraksi: elemen halaman dan tes. Saya menyoroti satu lagi - logika bisnis. Saya perhatikan bahwa cara Anda membangun kerangka kerja Anda akan sangat mempengaruhi kemudahan penulisan tes di masa depan, serta dukungan mereka. Saya mencoba untuk membuat kode tes terlihat seperti itu adalah tes normal yang ditulis oleh penguji biasa. Yaitu Saya mulai dari akhir:

  1. Saya menulis kode kasus tes yang indah dan jelas,
  2. Saya menerapkan metode dari kasus uji di lapisan logika bisnis,
  3. Saya menggambarkan elemen-elemen yang diperlukan untuk pengujian.

Pendekatan ini baik karena kita tidak melakukan apa-apa ekstra - kerangka kerja dibangun di atas sebanyak yang diperlukan agar tes dapat bekerja. Kita dapat mengatakan bahwa ini adalah konsep MVP dalam pengujian: mereka dengan cepat membuat karya, dan sudah mulai membawa manfaat. Jika Anda pertama kali menulis ribuan baris, menggambarkan halaman aplikasi Anda dan cara berinteraksi dengannya, dan setelah tiga bulan Anda keluar dari "lubang" untuk klik pertama dan menyadari bahwa Anda harus melakukan segalanya secara berbeda, maka sebagian besar kreasi Anda akan dikutuk selamanya " mengumpulkan debu ”di ruang bawah tanah git ... Seorang penguji sejati tahu bahwa semakin cepat bug ditemukan, semakin murah untuk memperbaikinya. Gunakan pendekatan ini dalam segala hal - menulis ujian dalam beberapa jam, mencobanya, tidak menyukainya - membuangnya, belajar pelajaran, melanjutkan.

Jadi inputnya adalah:

  • Aplikasi Android untuk perdagangan di bursa efek;
  • Java untuk bekerja di tumpukan yang sama dengan pengembang;
  • kerangka dasar Automator UI;
  • Anda perlu menulis tes masuk dalam aplikasi.

Persiapan proyek


Karena saya mencoba mengintegrasikan sebanyak mungkin ke dalam proses pengembangan, saya tidak mulai membuat proyek baru. Menurut dokumentasi , tes instrumental harus ditempatkan di folder src/androidTest/java . Dalam kasus saya, kolektor telah dikonfigurasikan, jika Anda memiliki sesuatu yang salah, kemudian baca tentang konfigurasi build . Kita juga membutuhkan lingkungan pengembangan, Android SDK, Emulator, alat, platform-alat dan platform yang diperlukan untuk emulator. Jika Anda menggunakan Android Studio, maka semua ini dapat diinstal dengan cepat melalui SDK Manager:



Lapisan uji


Seperti yang saya tulis di atas, kami akan mengotomatiskan uji masuk dalam aplikasi. Ingat bahwa kode harus terlihat seperti test case biasa:

Prasyarat: jalankan aplikasi.
Langkah 1: masuk menggunakan akun myLogin / myPassword.
Langkah 2: periksa nama pengguna saat ini.
Hasil yang Diharapkan: pengguna saat ini adalah Ivan Ivanov.

Penafian kecil: sesuai dengan praktik terbaik uji desain, pada prasyarat Anda perlu membuat / menemukan akun. Saya menghilangkan momen ini sebagai contoh sederhana.

Kelas kami akan terlihat seperti ini:

 @RunWith(AndroidJUnit4.class) public class LoginTests { private TestApplication myApp; @Before public void setUp() { myApp = new TestApplication(); } @Test public void testLogin() { myApp.login("myLogin","myPassword"); String currentUser = myApp.getCurrentUserName(); assertEquals("Wrong name", " ", currentUser); } @After public void tearDown() { myApp.close(); } } 

Logika bisnis


Tes menggunakan kelas TestApplication() dan dua metode: login() dan getCurrentUserName() . Plus, Anda memerlukan konstruktor kelas (meluncurkan aplikasi di dalamnya) dan metode close() . Bagian depan jelas:

 public class TestApplication { private UiDevice device; private PageObject page; public TestApplication() { } public void login(String login, String password) { } public String getCurrentUserName() { return "" } public void close() { } } 

Sebuah instance dari kelas kami akan memiliki dua variabel:

  • device , milik kelas android.support.test.uiautomator.UiDevice - melalui itu kita berinteraksi dengan perangkat kita;
  • page , kelas PageObject , yang akan kita buat di bagian selanjutnya.

Mari kita mulai dengan konstruktor. Di dalamnya, buat instance variabel kami dan jalankan aplikasi:

 public TestApplication() { // Connect to device device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.pressHome(); // Get launch intent String packageName = InstrumentationRegistry.getTargetContext() .getPackageName(); Context context = InstrumentationRegistry.getContext(); Intent intent = context.getPackageManager() .getLaunchIntentForPackage(packageName) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // Stat application context.startActivity(intent); // Get page objects page = new PageObject(device, packageName); } 

Beberapa tips untuk meluncurkan aplikasi
Untuk lebih mengontrol aplikasi yang sedang diuji, Anda dapat menambahkan harapan bagi peluncur untuk memulai (jika Anda menjalankan emulator "saat dingin") dan aplikasi itu sendiri. Ini juga disarankan dalam dokumentasi .

Catatan: menjalankan aplikasi melalui android.content.Context.getTargetContext() hanya cocok jika tes Anda dalam proyek yang sama dengan aplikasi itu sendiri. Jika secara terpisah, akan perlu dijalankan melalui menu.

Logika bisnis dari tes ini adalah langkah-langkah spesifik yang harus dilakukan pengguna untuk mendapatkan hasil yang bermakna (untuk pengguna). Masuk dengan ultrasound Anda sendiri adalah hasil yang signifikan. Langkah-langkah: klik tombol "Masuk", masukkan nama pengguna di bidang "Masuk", masukkan kata sandi di bidang "Kata Sandi", klik tombol "Masuk". Dengan demikian, metode kami diisi dengan langkah-langkah:

 public void login(String login, String password) { page.login().click(); page.loginEntry().setText(login); page.passwordEntry().setText(password); page.signIn().click(); } 

Untuk mendapatkan pengguna saat ini, semuanya lebih sederhana, cukup dapatkan nilai bidang:

 public String getCurrentUserName() { return page.currentUserName().getText(); } } 

Dan untuk menutup aplikasi, klik saja tombol Home:

 public void close() { device.pressHome(); } 

Deskripsi elemen halaman


Konsep lapisan ini adalah bahwa ia harus mengembalikan elemen yang siap digunakan (dalam konteks kami, ini adalah kelas android.support.test.uiautomator.UiObject2 ). Artinya, konsumen tidak perlu khawatir dengan keadaan objek, jika ia kembali, maka Anda dapat langsung berinteraksi dengannya: klik, isi atau baca teks. Ini adalah konsekuensi penting - di lapisan ini kita akan mewujudkan harapan:

 private UiObject2 getUiObject(BySelector selector) { return device.wait(Until.findObject(selector), 10000); } 

Metode yang didefinisikan di atas akan digunakan oleh antarmuka publik kelas PageObject kami. Contoh untuk bidang Login:

 public UiObject2 loginEntry() { return getUiObject(loginEntrySelector()); } 

Masih menentukan pemilih yang akan kita temukan bidangnya. Instance dari android.support.test.uiautomator.BySelector paling mudah diperoleh dengan menggunakan metode statis dari android.support.test.uiautomator.By . Saya setuju dengan pengembangan bahwa di mana pun, kapan pun memungkinkan, akan ada resource-id unik:

 private BySelector loginEntrySelector() { return By.res(packageName, "login"); } 

Lebih mudah untuk memeriksa antarmuka di utilitas uiautomatorviewer yang termasuk dalam paket alat (diinstal di bagian Persiapan):



Pilih elemen yang diinginkan dan di bagian Node detail kita melihat resource-id. Ini terdiri dari nama paket dan, pada kenyataannya, pengidentifikasi. Kami mendapat nama paket di konstruktor dari kelas TestApplication , dan menggunakannya saat membuat PageObject .

Kode lengkap:

PageObject kelas
 public class PageObject { private UiDevice device; private final String packageName; private BySelector loginButtonSelector() { return By.res(packageName, "user_view"); } private BySelector loginEntrySelector() { return By.res(packageName, "login"); } private BySelector passwordEntrySelector() { return By.res(packageName, "password"); } private BySelector signInSelector() { return By.res(packageName, "btnLogin"); } private BySelector userNameSelector() { return By.res(packageName, "user_name"); } public PageObject(UiDevice device, String packageName) { this.device = device; this.packageName = packageName; } public UiObject2 login() { return getUiObject(loginButtonSelector()); } public UiObject2 loginEntry() { return getUiObject(loginEntrySelector()); } public UiObject2 passwordEntry() { return getUiObject(passwordEntrySelector()); } public UiObject2 signIn() { return getUiObject(signInSelector()); } public UiObject2 currentUserName() { return getUiObject(userNameSelector()); } private UiObject2 getUiObject(BySelector selector) { return device.wait(Until.findObject(selector), 10000); } } 


Menjalankan tes


Itu saja, masih berjalan. Pertama, sambungkan ke perangkat atau mulai emulator. Periksa koneksi dengan perintah adb devices (utilitas adb adalah bagian dari platform-tools):

 List of devices attached emulator-5554 device 

Jika Anda memiliki gelar, maka lakukanlah

 gradlew.bat connectedAndroidTest 

dan nikmati bagaimana "robot yang disuntikkan, bukan manusia" (c).

Source: https://habr.com/ru/post/id416397/


All Articles