Xamarin.UITest

Xamarin.UITest adalah kerangka kerja pengujian C# menggunakan NUnit untuk Pengujian Penerimaan UI di aplikasi iOS dan Android. Ini terintegrasi erat dengan proyek Xamarin.iOS dan Xamarin.Android, tetapi juga dapat digunakan dengan proyek iOS dan Android asli. Xamarin.UITest adalah Pustaka Automation yang memungkinkan pengujian NUnit dijalankan di perangkat Android dan iOS. Pengujian berinteraksi dengan antarmuka pengguna seperti yang dilakukan pengguna: memasukkan teks, mengetuk tombol, dan gerakan - seperti gesek.

Biasanya, setiap Xamarin.UITest ditulis sebagai metode yang disebut sebagai [Test]. Kelas yang berisi pengujian dikenal sebagai [TestFixture]. Perlengkapan pengujian berisi satu pengujian atau grup pengujian. Perlengkapan juga bertanggung jawab untuk penyiapan untuk membuat uji coba dan pembersihan yang perlu dilakukan ketika pengujian selesai. Setiap pengujian harus mengikuti pola Arrange-Act-Assert :

  1. Susun: Pengujian akan menyiapkan kondisi dan menginisialisasi hal-hal sehingga pengujian dapat ditindaklanjuti.
  2. Act: Pengujian akan berinteraksi dengan aplikasi, memasukkan teks, menekan tombol, dan sebagainya.
  3. Assert: Tes memeriksa hasil tindakan yang dijalankan dalam langkah UU untuk menentukan kebenaran. Misalnya, aplikasi dapat memverifikasi bahwa pesan kesalahan tertentu ditampilkan.

Waktu terbaik untuk memulai Xamarin.UITest adalah selama pengembangan aplikasi seluler. Pengujian otomatis ditulis sebagai fitur sedang dikembangkan sesuai dengan langkah-langkah yang dijelaskan dalam daftar berikut:

  1. Kembangkan fitur di aplikasi Android atau iOS.
  2. Tulis pengujian dan jalankan secara lokal untuk memverifikasi fungsionalitas.
  3. Buat Uji Coba baru di Uji App Center, atau gunakan Uji Coba yang sudah ada.
  4. Kompilasi IPA atau APK lalu unggah bersama dengan pengujian ke App Center Test.
  5. Perbaiki masalah atau bug apa pun yang diekspos oleh App Center Test.
  6. Ulangi proses dengan beralih ke fitur berikutnya untuk aplikasi.

Untuk aplikasi yang ada yang tidak lagi dalam pengembangan aktif, mungkin tidak hemat biaya untuk menambahkan pengujian otomatis secara retroaktif. Sebaliknya, pendekatan yang lebih baik adalah menggunakan Xamarin.UITest saat memperbaiki bug. Misalnya, pertimbangkan aplikasi yang tidak memiliki pengujian otomatis, dan pengguna melaporkan bug. Pengembang yang ditetapkan untuk memperbaiki bug tersebut mungkin mengambil beberapa (atau semua) dari tindakan berikut:

  • Verifikasi bug atau regresi secara manual.
  • Tulis pengujian menggunakan Xamarin.UITest yang menunjukkan bug.
  • Kirim pengujian ke pengujian App Center untuk mendapatkan beberapa wawasan tentang cakupan dan dampak bug pada perangkat yang relevan.
  • Perbaiki bug.
  • Buktikan bahwa bug telah diperbaiki dengan Xamarin.UITest yang lewat.
  • Kirim perbaikan dan uji ke Pengujian App Center untuk memverifikasi bahwa bug telah diperbaiki pada perangkat yang relevan.
  • Periksa pengujian yang lolos ke kontrol versi.

Pengujian UI otomatis sangat bergantung pada menemukan dan berinteraksi dengan tampilan di layar. Xamarin.UITest membahas persyaratan ini dengan dua set API penting yang bekerja sama satu sama lain:

  1. Tindakan yang dapat dilakukan pada tampilan - Xamarin.UITest menyediakan API yang memungkinkan pengujian untuk mensimulasikan tindakan pengguna umum seperti mengetuk tampilan, memasukkan teks, atau menggesekkan pada tampilan.
  2. Kueri untuk menemukan tampilan di layar - Bagian dari kerangka kerja Xamarin.UITest adalah API yang akan menemukan tampilan di layar. Kueri menemukan tampilan pada durasi dengan memeriksa atribut untuk tampilan dan mengembalikan objek yang mungkin dikerjakan oleh tindakan. Mengkueri dengan cara seperti itu adalah teknik canggih yang memungkinkan pengujian ditulis untuk antarmuka pengguna apa pun ukuran layar, orientasi, atau tata letak

Untuk membantu menulis tes, Xamarin.UITest menyediakan read-eval-print-loop (REPL). REPL memungkinkan pengembang dan penguji berinteraksi dengan layar saat aplikasi berjalan dan menyederhanakan pembuatan kueri.

Memperkenalkan Xamarin.UITest API

Semua interaksi pengujian dengan aplikasi seluler terjadi melalui instans Xamarin.UITest.IApp. Antarmuka ini mendefinisikan metode yang penting bagi pengujian untuk berkolaborasi dengan aplikasi dan berinteraksi dengan antarmuka pengguna. Ada dua implementasi konkret dari antarmuka ini:

  • Xamarin.UITest.iOS.iOSApp Kelas ini akan mengotomatiskan pengujian terhadap iOS.
  • Xamarin.UITest.Android.AndroidApp Kelas ini untuk mengotomatiskan pengujian di Android.

iOSApp objek dan AndroidApp tidak diinstansiasi secara langsung. Sebaliknya, mereka dibuat menggunakan kelas pembantu ConfigureApp . Kelas ini adalah penyusun yang memastikan bahwa iOSApp atau AndroidApp dibuat dengan benar.

Sebaiknya gunakan instans baru IApp untuk setiap pengujian. Instans baru mencegah status dari satu pengujian yang meluap ke pengujian lain. Ada dua tempat di mana tes NUnit dapat menginisialisasi instans IApp:

  • SetUp Dalam metode Biasanya, perlengkapan pengujian adalah pengelompokan logis dari pengujian terkait, masing-masing berjalan independen dari yang lain. Dalam skenario ini, IApp harus diinisialisasi dalam SetUp metode , memastikan bahwa yang baru IApp tersedia untuk setiap pengujian.
  • TestFixtureSetup Dalam metode Dalam beberapa situasi, satu pengujian mungkin memerlukan perlengkapan pengujiannya sendiri. Dalam hal ini, mungkin lebih masuk akal untuk menginisialisasi IApp objek sekali dalam TestFixtureSetup metode .

Setelah IApp dikonfigurasi, pengujian dapat mulai berinteraksi dengan aplikasi yang sedang diuji. Untuk melakukannya, Anda perlu mendapatkan referensi ke tampilan yang terlihat di layar. Banyak metode di Xamarin.UITest mengambil Func<AppQuery, AppQuery> parameter untuk menemukan tampilan. Misalnya, cuplikan berikut menunjukkan cara mengetuk tombol:

app.Tap(c=>c.Button("ValidateButton"));

Ada dua implementasi IApp antarmuka dalam kerangka kerja Xamarin.UITest, satu untuk iOS dan satu untuk Android.

Menginisialisasi IApp untuk Aplikasi iOS

Ketika Xamarin.UITest menjalankan pengujian di iOS, Xamarin.UITest memulai instans simulator iOS, menyebarkan aplikasi, meluncurkannya, dan mulai menjalankan pengujian. Aplikasi iOS harus sudah dibuat. Xamarin.UITest tidak akan mengkompilasi aplikasi dan membuat App Bundle untuk Anda.

Metode AppBundle ini dapat digunakan untuk menentukan di mana pada sistem file bundel aplikasi dapat ditemukan. Ada dua cara untuk melakukannya, dengan jalur absolut, atau jalur relatif. Cuplikan ini menunjukkan menggunakan jalur absolut ke bundel aplikasi:

IApp app = ConfigureApp
    .iOS
    .AppBundle("/path/to/iosapp.app")
    .StartApp();

Jalur parsial harus relatif terhadap perakitan Xamarin.UITest. Cuplikan ini adalah contoh:

IApp app = ConfigureApp
    .iOS
    .AppBundle("../../../iOSAppProject/bin/iPhoneSimulator/Debug/iosapp.app")
    .StartApp();

Contoh jalur relatif memberi tahu AppBundle untuk naik tiga direktori dari rakitan Xamarin.UITest, lalu menavigasi ke bawah pohon proyek proyek aplikasi iOS untuk menemukan bundel aplikasi.

ConfigureApp memang memiliki metode lain untuk membantu mengonfigurasi IApp. Lihat kelas iOSAppConfigurator untuk detail selengkapnya. Beberapa metode yang lebih menarik dijelaskan dalam tabel berikut:

Metode Deskripsi
AppBundle Metode ini menentukan jalur ke app bundle untuk digunakan saat pengujian.
Debug Metode ini akan mengaktifkan pesan pengelogan debug di runner pengujian. Metode ini berguna untuk memecahkan masalah dalam menjalankan aplikasi pada simulator.
DeviceIdentifier Mengonfigurasi perangkat untuk digunakan dengan pengidentifikasi perangkat. Metode ini akan dijelaskan secara lebih rinci di bawah ini.
EnableLocalScreenshots Aktifkan cuplikan layar saat menjalankan pengujian secara lokal. Cuplikan layar selalu diaktifkan saat pengujian berjalan di cloud.

Untuk informasi selengkapnya tentang cara menjalankan pengujian iOS pada Simulator iOS tertentu, lihat Menentukan ID Perangkat untuk Simulator iOS.

Menginisialisasi IApp untuk Aplikasi Android

Xamarin.UITest akan menyebarkan APK yang ada ke perangkat yang terpasang atau instans emulator Android yang sudah berjalan. Aplikasi akan dimulai, dan kemudian pengujian akan dijalankan. Xamarin.UITest tidak dapat membuat APK juga tidak dapat memulai instans emulator Android.

Metode ApkFile digunakan IApp untuk menentukan di mana pada sistem file APK dapat ditemukan. Ada dua cara untuk melakukannya, dengan jalur absolut, atau jalur relatif. Cuplikan ini menunjukkan menggunakan jalur absolut ke APK:

IApp app = ConfigureApp
    .Android
    .ApkFile("/path/to/android.apk")
    .StartApp();

Jalur parsial harus relatif terhadap perakitan Xamarin.UITest. Cuplikan ini adalah contoh:

IApp app = ConfigureApp
    .Android
    .ApkFile("../../../AndroidProject/bin/Debug/android.apk")
    .StartApp();

Contoh jalur relatif memberi tahu ApkFile untuk naik tiga direktori dari rakitan Xamarin.UITest, dan kemudian menavigasi ke bawah pohon proyek proyek aplikasi Android untuk menemukan file apk.

Jika ada lebih dari satu perangkat atau emulator yang terhubung, Xamarin.UITest akan menghentikan eksekusi pengujian dan menampilkan pesan kesalahan karena tidak dapat menyelesaikan target yang dimaksudkan untuk pengujian. Dalam hal ini, perlu untuk memberikan ID serial perangkat atau emulator untuk menjalankan pengujian. Misalnya, pertimbangkan output berikut dari adb devices perintah yang mencantumkan semua perangkat (atau emulator) yang terpasang pada komputer (bersama dengan ID serialnya):

$ adb devices
List of devices attached
192.168.56.101:5555 device
03f80ddae07844d3    device

Perangkat dapat ditentukan menggunakan DeviceSerial metode :

IApp app = ConfigureApp.Android.ApkFile("/path/to/android.apk")
                               .DeviceSerial("03f80ddae07844d3")
                               .StartApp();

Berinteraksi dengan Antarmuka Pengguna

Untuk berinteraksi dengan tampilan, banyak IApp metode mengambil Func<AppQuery, AppQuery> delegasi untuk menemukan tampilan. Delegasi ini menggunakan AppQuery yang menjadi inti dari bagaimana Xamarin.UITest menemukan tampilan.

AppQuery adalah antarmuka yang fasih untuk membangun kueri untuk menemukan tampilan. Dari metode yang AppQuery menyediakan, Marked metode ini adalah salah satu yang paling sederhana dan paling fleksibel. Metode ini menggunakan heuristik untuk mencoba menemukan tampilan dan akan dibahas secara lebih rinci di bagian berikut. Untuk saat ini, penting untuk dipahami bahwa IApp memiliki banyak metode untuk berinteraksi dengan aplikasi. Metode ini menggunakan Func<AppQuery, AppQuery> untuk mendapatkan referensi ke tampilan untuk berinteraksi. Beberapa metode yang lebih menarik disediakan oleh AppQuery tercantum di bawah ini:

Metode Deskripsi
Button Akan menemukan satu atau beberapa tombol di layar.
Class Akan mencoba menemukan tampilan yang berasal dari kelas tertentu.
Id Akan mencoba menemukan tampilan dengan Id yang ditentukan.
Index . Akan mengembalikan satu tampilan dari kumpulan tampilan yang cocok. Biasanya digunakan bersama dengan metode lain. Mengambil indeks berbasis nol.
Marked Akan mengembalikan pandangan sesuai dengan heuristik yang dibahas di bawah ini.
Text Akan cocok dengan tampilan yang berisi teks yang disediakan.
TextField Akan cocok dengan Android EditText atau iOS UITextField.

Misalnya, metode berikut menunjukkan cara mensimulasikan ketukan pada tombol yang disebut "SaveUserdataButton":

app.Tap(c=>c.Marked("SaveUserDataButton"));

Karena AppQuery merupakan antarmuka yang fasih, dimungkinkan untuk menyatukan beberapa pemanggilan metode bersama-sama. Pertimbangkan contoh ketukan pada tampilan yang lebih rumit ini:

app.Tap(c=>c.Marked("Pending")
            .Parent()
            .Class("AppointmentListCell").Index(0));

Di sini, pertama-tama AppQuery akan menemukan tampilan yang ditandai Pending, lalu pilih induk pertama tampilan tersebut yang merupakan AppointmentListCell jenis.

Mungkin sulit mencoba membuat kueri ini dengan melihat aplikasi seluler. Xamarin.UITest menyediakan REPL yang dapat digunakan untuk menjelajahi hierarki tampilan layar, bereksperimen dengan membuat kueri, dan menggunakannya untuk berinteraksi dengan aplikasi.

Menggunakan REPL

Satu-satunya cara untuk memulai REPL adalah dengan memanggil IApp.Repl metode dalam pengujian yang ada. Ini mengharuskan membuat NUnit TestFixture, mengonfigurasi instans IApp yang dapat digunakan dalam Test metode . Cuplikan kode berikut menunjukkan contoh cara melakukannya:

[TestFixture]
public class ValidateCreditCard
{
    IApp app;

    [SetUp]
    public void Setup()
    {
        app = ConfigureApp.Android.ApkFile("/path/to/application.apk").StartApp();
    }
    [Test]
    public void CreditCardNumber_TooLong_DisplayErrorMessage()
    {
        app.Repl();
    }
}

Untuk menjalankan pengujian dengan mengklik kanan di selokan Visual Studio dan memilih Jalankan:

Cuplikan layar menu popup dengan opsi jalankan untuk pengujian

Pengujian akan berjalan, dan ketika Repl metode dipanggil, Xamarin.UITest akan memulai REPL dalam sesi terminal, seperti yang ditunjukkan pada cuplikan layar berikut:

Cuplikan layar terminal macOS yang menjalankan Xamarin.UITest REPL

REPL telah menginisialisasi instans IApp yang disebut app, yang berinteraksi dengan aplikasi. Salah satu hal pertama yang harus dilakukan adalah menjelajahi antarmuka pengguna. REPL memiliki tree perintah untuk melakukan itu. Ini akan mencetak hierarki tampilan di layar yang ditampilkan. Sebagai contoh, pertimbangkan cuplikan layar aplikasi berikut:

Cuplikan layar aplikasi sampel yang berjalan di iPhone

Kita dapat menggunakan tree perintah untuk menampilkan hierarki berikut dari layar ini:

App has been initialized to the 'app' variable.
Exit REPL with ctrl-c or see help for more commands.

>>> tree
[UIWindow > UILayoutContainerView]
  [UINavigationTransitionView > ... > UIView]
    [UITextView] id: "CreditCardTextField"
      [_UITextContainerView]
    [UIButton] id: "ValidateButton"
      [UIButtonLabel] text: "Validate Credit Card"
    [UILabel] id: "ErrorrMessagesTestField"
  [UINavigationBar] id: "Credit Card Validation"
    [_UINavigationBarBackground]
      [_UIBackdropView > _UIBackdropEffectView]
      [UIImageView]
    [UINavigationItemView]
      [UILabel] text: "Credit Card Validation"
>>>

Kita dapat melihat bahwa ada UIButton dalam tampilan ini dengan idValidateButton. Kita dapat menggunakan informasi yang ditampilkan oleh tree perintah untuk membantu membuat kueri yang diperlukan untuk menemukan dan berinteraksi dengan tampilan. Misalnya, kode berikut mensimulasikan ketukan pada tombol:

app.Tap(c=>c.Marked("ValidateButton"))

Saat perintah dimasukkan, perintah tersebut diingat oleh REPL dalam buffer. REPL menyediakan copy perintah yang akan menyalin isi buffer ini ke clipboard. Ini memungkinkan kita untuk membuat prototipe tes. Kita dapat menyalin pekerjaan yang dilakukan di REPL ke clipboard dengan copy, lalu menempelkan perintah tersebut di dalam [Test].

Menggunakan ditandai untuk menemukan tampilan

Metode AppQuery.Marked adalah cara yang nyaman dan kuat untuk mengkueri tampilan di layar. Ini bekerja dengan memeriksa hierarki tampilan untuk tampilan di layar, mencoba mencocokkan properti pada tampilan dengan string yang disediakan. Marked bekerja secara berbeda tergantung pada sistem operasi.

Menemukan Tampilan iOS dengan Ditandai

Tampilan iOS akan ditemukan menggunakan salah satu atribut berikut:

  • tampilan AccessibilityIdentifier
  • tampilan AccessibilityLabel

Sebagai contoh, pertimbangkan cuplikan C# berikut yang membuat UILabel dan menetapkan AccessibilityLabel:

UILabel errorMessagesTextField = new UILabel(new RectangleF(10, 210, 300, 40));
errorMessagesTextField.AccessibilityLabel = "ErrorMessagesTextField";
errorMessagesTextField.Text = String.Empty;

Tampilan ini dapat ditemukan oleh kueri berikut:

AppResult[] results = app.Marked("ErrorMessagesTextField");

Menemukan Tampilan Android dengan Ditandai

Tampilan Android akan ditemukan berdasarkan salah satu properti berikut:

  • tampilan Id
  • tampilan ContentDescription
  • tampilan Text

Misalnya, pertimbangkan tata letak Android yang memiliki tombol berikut yang ditentukan:

<Button
    android:text="Action 1"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/action1_button"
    android:layout_weight="1"
    android:layout_marginLeft="5dp" />

Kita dapat melihat bahwa tombol android:id ini action1_button dan bahwa android:text adalah Tindakan 1. Salah satu dari dua kueri berikut akan menemukan tombol di layar:

  • app.Query(c=>c.Marked("action1_button"));
  • app.Query(c=>c.Marked("Action 1"));

Mengontrol Aplikasi dengan Xamarin.UITest.IApp

Setelah IApp dikonfigurasi dan diinisialisasi, pengujian dapat mulai berinteraksi dengan aplikasi. Salah satu contoh metode yang digunakan Func<AppQuery, AppQuery> adalah IApp.Query() metode . Metode ini akan menjalankan kueri dan mengembalikan hasilnya. Contoh paling sederhana ditampilkan dalam cuplikan berikut, yang mengembalikan daftar semua tampilan yang terlihat di layar:

AppResult[] results = app.Query(c=>c.All())

Tabel berikut menunjukkan beberapa contoh lain penggunaan AppQuery untuk menemukan tampilan di layar:

Sintaks Hasil
app.Query(c=>c.Class("UILabel")) Metode ini .Class() akan mengkueri tampilan yang merupakan subkelas dari iOS UILabel.
app.Query(c=>c.Id("txtUserName")) Metode ini .Id() akan mengkueri tampilan dengan IdtxtUserName.
app.Query(c=>c.Class("UILabel").Text("Hello, World")) Menemukan semua UILabel kelas yang memiliki teks "Halo, Dunia".
results = app.Query(c=>c.Marked("ValidateButton")) Mengembalikan semua tampilan yang ditandai dengan teks yang ditentukan. Metode Marked ini adalah metode berguna yang dapat menyederhanakan kueri. Ini akan dibahas di bagian berikut.

Tabel berikutnya mencantumkan beberapa (tetapi tidak semua) dari metode yang disediakan oleh IApp yang dapat digunakan untuk berinteraksi dengan atau memanipulasi tampilan di layar:

Contoh Deskripsi
PressEnter Tekan tombol enter di aplikasi.
Tap Mensimulasikan gerakan ketuk/sentuh pada elemen yang cocok.
EnterText Memasukkan teks ke dalam tampilan. Dalam aplikasi iOS, Xamarin.UITest akan memasukkan teks menggunakan keyboard lunak. Sebaliknya, Xamarin.UITest tidak akan menggunakan keyboard Android, itu akan langsung memasukkan teks ke dalam tampilan.
WaitForElement Menjeda eksekusi pengujian hingga tampilan muncul di layar.
Screenshot(String) Mengambil cuplikan layar aplikasi dalam statusnya saat ini dan menyimpannya ke disk. Ini mengembalikan FileInfo objek dengan informasi tentang cuplikan layar yang diambil.
Flash Metode ini akan menyebabkan tampilan yang dipilih menjadi "flash" atau "berkedip" pada layar.

Untuk informasi selengkapnya tentang IApp antarmuka, lihat dokumentasi API untuk IApp, , AndroidAppdan iOSApp.

Sebagai contoh cara menggunakan metode ini, pertimbangkan pengujian berikut untuk cuplikan layar yang ditampilkan di atas. Pengujian ini akan memasukkan nomor 17 digit untuk kartu kredit ke dalam bidang teks lalu mengetuk tombol di layar. Kemudian akan memeriksa layar untuk pesan kesalahan yang memberi tahu pengguna bahwa nomor tersebut terlalu panjang untuk menjadi nomor kartu kredit yang valid:

[Test]
public void CreditCardNumber_TooLong_DisplayErrorMessage()
{
    /* Arrange - set up our queries for the views */
    // Nothing to do here, app has been instantiated in the [SetUp] method.

    /* Act */
    app.EnterText(c => c.Marked("CreditCardTextField"), new string('9', 17));
    // Screenshot can be used to break this test up into "steps".
    // The screenshot can be inspected after the test run to verify
    // the visual correctness of the screen.
    app.Screenshot("Entering a 17 digit credit card number.");

    app.Tap(c => c.Marked("ValidateButton"));
    app.Screenshot("The validation results.");

    /* Assert */
    AppResult[] result = app.Query(c => c.Class("UILabel").Text("Credit card number is too long."));
    Assert.IsTrue(result.Any(), "The error message isn't being displayed.");
}

Pengujian ini juga menggunakan Screenshot metode untuk mengambil gambar di titik kunci selama eksekusi pengujian. Saat pengujian ini dijalankan, App Center akan mengambil cuplikan layar dan menampilkannya dalam hasil pengujian. Metode ini memungkinkan memecah pengujian menjadi langkah-langkah dan memberikan deskripsi untuk cuplikan layar.