Saya mencoba menulis tes unit UI untuk aplikasi GUI saya dan saya menghadapi masalah itu, ketika mereka bekerja dengan baik ketika saya awalnya menulis mereka, mereka ternyata rapuh dan mereka pecah setiap kali perubahan desain (yaitu, cukup sering). Saya berjuang untuk menemukan serangkaian pedoman yang akan menuntun saya untuk memiliki unit test yang dapat dipertahankan untuk GUI.
Untuk saat ini, satu hal yang saya temukan adalah tes yang mengatakan "komponen ini harus menunjukkan data inputnya di suatu tempat" adalah baik (dan itu sangat mudah dengan HTML). Tes yang memeriksa keadaan spesifik dari bagian tertentu dari komponen biasanya rapuh. Pengujian akan seperti klik-klik-klik-harapkan, yang mencoba mengikuti perilaku pengguna dan logika bisnis yang mendasarinya (yang merupakan bagian paling penting) biasanya berubah menjadi rapuh. Bagaimana cara menulis tes yang bagus?
Untuk lebih tepatnya, saya ingin tahu beberapa pola tentang apa yang bisa saya uji di UI saya, bukan bagaimana cara mengujinya. Konvensi penamaan dan pengidentifikasi tetap baik, tetapi tidak menyelesaikan masalah inti, yaitu, bahwa GUI banyak berubah. Saya ingin menguji perilaku yang paling tidak mungkin berubah. Bagaimana cara menemukan hal yang benar untuk diuji?
Jawaban:
Masalah umum dengan tes GUI ... Alasan utama tes ini dianggap rapuh adalah karena mereka tidak dapat bertahan dari perubahan dalam GUI yang bukan merupakan perubahan dalam persyaratan . Anda harus berusaha untuk menyusun kode tes Anda sedemikian rupa sehingga perubahan dalam GUI diisolasi ke satu tempat dalam tes.
Sebagai contoh, pertimbangkan tes yang diucapkan sebagai:
Banyak ruang di sini untuk pengujian ini untuk dipecahkan ketika Anda mengerjakan ulang antarmuka, bahkan jika persyaratan untuk validasi tetap ada.
Sekarang, mari kita letakkan ini ke dalam sedikit alternatif kata-kata:
Tesnya sama, persyaratannya sama, tetapi tes semacam ini akan bertahan dari perubahan untuk UI Anda. Anda perlu mengubah kode, tentu saja, tetapi kode tersebut akan terisolasi. Bahkan jika Anda memiliki sepuluh atau dua puluh tes seperti itu untuk halaman profil Anda dan Anda memindahkan logika validasi errormessage-displaying Anda dari javascript-alert ke jquery-popups misalnya, Anda hanya perlu mengubah bagian uji tunggal yang memeriksa pesan kesalahan.
sumber
Ini adalah masalah umum. Saya akan memperhatikan:
Bagaimana Anda menyebutkan elemen
Gunakan id atau kelas css untuk mengidentifikasi elemen. Favour menggunakan ID CSS saat objek unik. Pertimbangkan kerangka kerja yang Anda gunakan, misalnya dengan Ruby on Rails,
name
atribut ditetapkan secara otomatis dan dapat (non-intuitif) lebih baik daripada menggunakan css id atau kelasBagaimana Anda mengidentifikasi elemen.
Hindari pengidentifikasi posisi seperti yang
table/tr/td/td
mendukung formulir sepertitd[id="main_vehicle"
atautd[class='alternates']
. Pertimbangkan untuk menggunakan atribut data bila perlu. Bahkan lebih baik mencoba untuk menghindari tag tata letak seperti<td>
semuanya jadi untuk di atas Anda bisa menambahkan span dan menggunakannya, misalnya<span id="main_vehicle">
atau pemilih wildcard seperti di*[id="main_vehicle"]
mana*
sekarang bisa menjadi div, span, td, dll.Menggunakan uji atribut data spesifik yang hanya digunakan untuk qa dan pengujian.
Hindari kualifikasi yang tidak perlu untuk elemen. Anda mungkin menemukan diri Anda menggunakan yang berikut ini:
body.main div#vehicles > form#vehicle input#primary_vehicle_name
Namun ini mengharuskan bidang input untuk tetap dalam bentuk dengan id kendaraan yang tepat dan pada halaman dengan tubuh yang memiliki kelas utama dan div dengan id kendaraan yang memiliki anak langsung dari bentuk dengan id dari kendaraan. Setiap perubahan pada salah satu dari struktur itu dan tes rusak Dalam hal ini Anda mungkin menemukan itu
input#primary_vehicle_name
cukup untuk mengidentifikasi elemen secara unik.
Hindari tes yang merujuk pada teks yang terlihat. Teks pada halaman yang ditampilkan kepada pengguna biasanya berubah seiring berjalannya waktu ketika situs tersebut dikelola dan diperbarui, jadi gunakan pengidentifikasi seperti css id dan css class atau atribut data. Elemen seperti
form
,input
danselect
digunakan dalam bentuk juga merupakan bagian yang baik dari elemen pengidentifikasi, biasanya dalam kombinasi dengan id atau kelas, misalnyali.vehicle
atauinput#first-vehicle
Anda juga dapat menambahkan pengidentifikasi Anda sendiri, misalnya<div data-vehicle='dodge'>
. Dengan cara ini Anda dapat menghindari penggunaan ID elemen atau kelas, yang kemungkinan akan diubah oleh pengembang dan perancang. Saya sebenarnya menemukan dari waktu ke waktu bahwa lebih baik bekerja dengan pengembang dan desainer dan mencapai kesepakatan atas nama dan cakupan. Itu susah.Bagaimana data tetap dipertahankan.
Mirip dengan mengidentifikasi elemen yang sebenarnya, cobalah untuk menghindari nilai identifikasi selektor kode in-line yang mendukung objek halaman - potongan kecil teks yang disimpan dalam variabel atau metode dan dengan demikian dapat digunakan kembali dan juga dipelihara secara terpusat. Contoh variabel javascript yang mengikuti pola ini untuk nilai hard-coded:
Lebih banyak pada objek halaman di selenium wiki dan selenium docs
Komunikasi dengan pengembang.
Terlepas dari pendekatan teknis dalam hal 'pengembang melakukan perubahan dan memutus otomatisasi QA' yang merupakan masalah alur kerja. Anda perlu memastikan bahwa: semua orang adalah satu tim yang sama; pengembang menjalankan tes terintegrasi yang sama; standar disepakati dan diikuti oleh kedua kelompok; definisi yang dilakukan mencakup menjalankan dan mungkin memperbarui tes UI; pengembang dan pasangan penguji pada rencana pengujian dan keduanya menghadiri perawatan tiket (jika melakukan Agile) dan berbicara tentang pengujian UI sebagai bagian dari perawatan. Anda harus memastikan bahwa pendekatan dan strategi apa pun yang Anda gunakan untuk penamaan dikoordinasikan dengan pengembang aplikasi. Jika Anda tidak masuk ke halaman yang sama, Anda akan menyukai clash over penamaan objek. Beberapa contoh metode objek halaman yang baru-baru ini saya buat untuk proyek ruby:
Berikut objek halaman yang sama dengan variabel javascript:
sumber
Alasan mengapa orang mengembangkan hal-hal seperti MVC, MVP dan presenter terlebih dahulu, dan pola desain yang serupa, adalah untuk memisahkan logika bisnis dari antarmuka pengguna.
Jelas, bagian tampilan hanya dapat diuji dengan memulai program, dan memeriksa apa yang ditampilkan - dengan kata lain, itu hanya dapat diuji dalam tes penerimaan.
Di sisi lain, pengujian logika bisnis dapat dilakukan dalam unit test. Dan itu adalah jawaban untuk pertanyaan Anda. Uji semua yang ada dalam model, dan jika Anda bisa dan mau, Anda juga bisa menguji kode pengontrol.
Itu hanya bisa terjadi ketika Anda mengubah persyaratan. Ketika persyaratan berubah, tidak ada jalan lain, kecuali mengubah kode. Jika Anda berhasil membuat desain dan arsitektur yang baik, perubahan tidak akan menyebar di banyak tempat.
sumber
Tes interaksi GUI harus tidak lebih atau kurang rapuh daripada jenis tes lainnya. Itu adalah; jika aplikasi Anda berubah dalam beberapa cara, tes perlu diperbarui untuk mencerminkan hal itu.
Sebagai perbandingan:
Tes Unit
Asli :
validateEmail()
harus melemparInvalidData
pengecualian. Yang tercakup dengan benar dalam unit test Anda.Ubah :
validateEmail()
harus melemparInvalidEmail
pengecualian. Sekarang tes Anda salah, Anda memperbaruinya, dan semuanya berwarna hijau lagi.Tes GUI
Asli : Memasukkan email yang tidak valid akan menghasilkan kotak kesalahan sembulan yang berisi "Data yang dimasukkan tidak valid". Terdeteksi dengan benar oleh tes Anda.
Ubah : Memasukkan email yang tidak valid akan menghasilkan kesalahan sebaris yang berisi "Email yang dimasukkan salah". Sekarang tes Anda salah, Anda memperbaruinya, dan semuanya berwarna hijau lagi.
Ingatlah bahwa Anda menguji input dan output - beberapa perilaku yang didefinisikan dengan baik. Terlepas dari apakah itu tes GUI atau tes Unit atau tes Integrasi, dll.
sumber