Day 3: Behavior-Driven Development (BDD)
- Session 1: 09:00 - 10:15: Overview BDD
- Session 2: 10:30 - 11:45: Hands-on: A Case study
- Session 3: 13:00 - 15:00: Hands-on: A Case study
- Session 4: 15:30 - 16:30: Overview, Discussion, Lesson learned
Functional Tests & BDD
Anda telah diperkenalkan dengan contoh kode test dari tingkat unit test hingga functional test di hari pertama workshop. Unit test menguji komponen software terkecil ("unit", seperti fungsi dan method) secara independen dan, idealnya, terisolasi dari komponen lainnya. Sedangkan functional test menguji software secara utuh dengan menyimulasikan interaksi pengguna ketika menggunakan software.
Hari ini kita akan melihat bagaimana functional test dapat dikembangkan lebih lanjut untuk mendukung proses pengembangan software dengan gaya Behavior-Driven Development (BDD). Sebagai contoh, berikut ini adalah potongak kode sebuah test case dari functional test suite Sitodo PMPL yang menyimulasikan aksi menambahkan todo item baru:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Dapat dilihat bahwa alur uji coba dituliskan secara imperatif oleh developer. Developer mengimplementasikan serangkaian instruksi kepada "aktor" (dalam hal ini, browser yang dikendalikan Selenium WebDriver) untuk dapat menyimulasikan alur penggunaan sebuah fitur pada software yang sedang diujicobakan (System Under Test, disingkat SUT). Kumpulan instruksi tersebut seringkali sangat teknis dan sulit untuk dipahami oleh anggota tim selain developer, terutama anggota tim yang fokus pada aspek bisnis (requirements) dan penjaminan mutu.
Walaupun developer bisa meningkatkan readability kode dengan memberikan nama test case secara deskriptif serta menuliskan kode dengan gaya penulisan mengikuti bahasa natural (seringkali disebut sebagai fluent-style), functional test masih terpisah dari kebutuhan (requirements) pengembangan sehingga tidak ada keterkaitan (traceability) antara requirements dengan test.
BDD hadir untuk berusaha menjembatani tiga peran dalam pengembangan: bisnis, tim pengembang, dan penjaminan mutu. Ketiga peran tersebut berkolaborasi dalam proses pengembangan dengan menyusun requirements yang traceable dari deskripsi, implementasi, dan uji cobanya.
Persiapan Workshop
Untuk mengikuti rangkaian kegiatan workshop hari ini, harap persiapkan tools berikut di komputer:
- Git
- Java JDK 17
- IntelliJ IDEA Community Edition
- Harap pasang plugin Cucumber yang dapat diunduh melalui menu Plugins > Marketplace di dalam IntelliJ IDEA.
- Apache Maven
- Web browser seperti Mozilla Firefox atau Google Chrome.
- (Opsional) Docker dan Docker Compose apabila ingin menjalankan contoh proyek di dalam container. Catatan instalasi Docker dapat dilihat di halaman berikut: (klik)
- (Opsional) Node.js versi 16 apabila ingin menjalankan frontend aplikasi contoh secara lokal.
Pastikan anda dapat memanggil program-program berikut dari dalam shell favorit anda:
1 2 3 4 |
|
Hasil pemanggilan program-program di atas seharusnya akan mencetak versi program yang terpasang di komputer anda.
Buka proyek Spring Petclinic BDD di GitLab CSUI
dan buat salinan proyek (fork) ke dalam akun GitLab CSUI anda.
Kemudian buat salinan kode templat dari fork ke komputer anda menggunakan perintah git
:
1 |
|
Proyek tersebut mengandung kode templat awal untuk berlatih membuat test suite BDD yang akan diujikan terhadap aplikasi Spring Petclinic. Sudah tersedia aplikasi Spring Petclinic bagi masing-masing peserta yang dapat dicoba secara daring. Berikut ini adalah tautan ke aplikasi Spring Petclinic bagi setiap peserta:
https://spring-petclinic-angular-fatimah.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-rezha.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-sri.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-wida.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-niea.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-yopi.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-budi.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-winayaka.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-fakhri.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-ratu.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-adit.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-meitya.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-ganda.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-pahmil.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-sonya.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-kamrozi.dokku-ppl.cs.ui.ac.id
https://spring-petclinic-angular-agra.dokku-ppl.cs.ui.ac.id
Catatan: Mohon hanya akses aplikasi Spring Petclinic sesuai nama depan masing-masing!
Sebagai alternatif bagi peserta yang ingin mencoba menjalankan aplikasinya secara lokal,
tersedia juga berkas docker-compose.yml
berikut untuk menjalankan aplikasi Spring Petclinic:
1 2 3 4 5 6 7 8 9 10 |
|
Backend aplikasi Spring Petclinic menggunakan Spring Petclinic REST yang dapat diakses melalui port 9966 di 127.0.0.1
.
Sedangkan frontend aplikasi menggunakan Spring Petclinic Angular yang dapat diakses melalui port 80 di 127.0.0.1
.
Kedua komponen aplikasi ini dapat jalan sebagai container, ataupun di-build secara manual.
Silakan merujuk ke README.md
masing-masing komponen jika ingin menjalankannya secara manual (tanpa container).
Apabila sudah menyalin repositori Git dan telah menyiapkan tools yang dibutuhkan, silakan coba jalankan terlebih dahulu aplikasi contoh:
1 2 3 |
|
Kemudian buka laman depan aplikasi menggunakan web browser seperti Google Chrome di alamat aplikasi atas nama anda
atau di http://127.0.0.1
jika anda menjalankannya secara lokal.
Tampilan aplikasi akan terlihat serupa dengan screenshot berikut:
Templat Kode Spring Petclinic BDD
Templat kode yang digunakan pada workshop hari ini mengadopsi templat starter code Serenity & Cucumber. Templat kode telah dimodifikasi agar dapat menggunakan contoh aplikasi Spring Petclinic secara lokal menggunakan container.
Sesuai dengan nama templat starter code asli yang digunakan, kita akan menggunakan Serenity dan Cucumber. Serenity merupakan test framework yang menyediakan library dan mendukung proses otomasi test yang mengikuti alur BDD. Sedangkan Cucumber menyediakan library untuk menuliskan deskripsi fitur pada test suite BDD dan menyambungkannya ke test framework seperti Serenity.
Menulis Deskripsi Fitur & Skenario Test Dengan Gherkin
Ingat kembali bahwa salah satu tujuan BDD adalah ingin menjembatani peran non-teknis (misal: client, analis) dengan peran teknis (misal: tim pengembang). Peran non-teknis akan berkolaborasi lebih erat dengan peran teknis selama proses pengembangan berlangsung. Bentuk kolaborasi lebih erat ini salah satunya dituangkan dalam bentuk keterlibatan peran non-teknis dalam membuat deskripsi fitur serta menyusun skenario test fitur tersebut.
Peran non-teknis dapat membuat deskripsi fitur dan skenario test dengan menggunakan bahasa Gherkin. Gherkin adalah bahasa dengan struktur yang sederhana dan dituliskan menggunakan sintaks bahasa natural. Deskripsi fitur dan skenario test dapat dituliskan menggunakan Gherkin seperti menuliskan prosa dalam bahasa natural. Tentu saja ada aturan sintaks dan struktur yang harus diikuti agar dapat dijalankan oleh test framework.
Sebagai contoh, mari lihat potongan contoh skenario test berikut yang dapat ditemukan di src/test/resources/features/veterinarian/manage_specialties.feature
:
1 2 3 4 5 6 7 |
|
Skenario test dituliskan sebagai bagian dari deskripsi fitur yang dituliskan dalam berkas dengan ekstensi .feature
.
Pada contoh di atas, deskripsi fitur dimulai dengan teks Feature: Manage specialties
yang berarti berkas ini merupakan deskripsi fitur "Manage specialties".
Selanjutnya, terdapat teks bebas yang menjelaskan lebih rinci fitur terkait.
Teks bebas tersebut dapat juga berisi dengan deskripsi use case atau user story.
Sebuah fitur dapat memiliki satu atau lebih skenario test.
Pada contoh di atas, saat ini hanya ada sebuah skenario test untuk menguji fitur menambahkan bidang spesialis dokter hewan.
Skenario test berisi tiga buah komponen penting di dalam membuat instruksi pengujian dengan gaya BDD: Given
, When
, dan Then
.
Given
merepresentasikan kondisi awal skenario test sebelum menjalankan aksi aktor.
When
merepresentasikan aksi aktor dalam SUT.
Then
merepresentasikan kondisi akhir skenario test setelah menjalankan aksi aktor.
Berikut ini adalah daftar referensi terkait sintaks Gherkin yang direkomendasikan:
Latihan Singkat: Menulis Deskripsi Fitur & Skenario Test Baru
Mari coba membuat sebuah deskripsi fitur beserta sebuah skenario test baru. Silakan ikuti tasks berikut:
- Buat berkas deskripsi fitur baru bernama
manage_pet_types.feature
disrc/test/resources/features/veterinarian
. - Tulis nama fitur baru "Manage pet types" beserta deskripsi singkatnya.
- Susun sebuah skenario test baru bernama "Add new pet type" yang menguji operator sistem dapat menambahkan sebuah jenis binatang peliharaan baru ke dalam sistem.
Tulis skenarionya mengikuti kerangka
Given
,When
, danThen
.
Salah satu contoh solusi dari latihan mandiri dapat dilihat pada contoh kode berikut:
1 2 3 4 5 6 7 |
|
Apabila telah selesai, simpan hasil pekerjaan. Buat commit Git dan push ke "fork" di GitLab CSUI.
Menjalankan Test Suite BDD
Test suite BDD dapat dijalankan dengan dua cara
yaitu menggunakan IDE (IntelliJ IDEA) atau menggunakan Maven di shell.
Jika anda ingin menjalankan test suite BDD menggunakan IDE,
maka buka berkas class Java yang merepresentasikan test suite BDD,
yaitu class CucumberTestSuite
di IDE.
Kemudian jalankan class tersebut dengan menekan tombol yang muncul di sisi kiri editor pada IDE
dan pilih Run 'CucumberTestSuite' seperti yang tergambarkan di screenshot berikut:
Jika nyaman menggunakan shell atau ingin menjalankan test suite BDD di lingkungan Continuous Integration (CI), panggil perintah Maven berikut di shell:
1 |
|
Test suite BDD akan dijalankan oleh test runner secara headless terhadap aplikasi yang berjalan secara lokal.
Begitu test suite BDD selesai dijalankan, laporan hasil test dapat ditemukan di folder target/site/serenity
.
Apabila menggunakan Maven, perintah mvn verify
juga akan menghasilkan laporan komplit hasil test sebagai dokumen HTML.
Contoh tampilan laporannya dapat dilihat pada screenshot berikut:
Jika mengacu pada contoh laporan di atas, dapat dilihat contoh test suite BDD mengandung tiga buah test case. Dari tiga test case tersebut, dua test case berhasil dan satu test case gagal.
Deskripsi fitur memang bermanfaat bagi peran non-teknis agar dapat ikut berkontribusi di dalam proses pengembangan. Namun bukan berarti deskripsi fitur dan skenario test secara ajaib bisa otomatis menguji coba SUT sesuai keinginan. Peran teknis seperti programmer dan test engineer penting untuk dapat menyambungkan deskripsi fitur ke kode test.
Catatan: Salah satu masalah yang umum terjadi ketika melakukan uji coba fungsionalitas melalui simulasi interaksi pada user interface adalah hasil test yang tidak stabil. Ada kemungkinan skenario uji coba yang dijalankan oleh kode test tidak berhasil berinteraksi dengan elemen user interface yang diinginkan. Pada aplikasi Web, isu elemen user interface yang gagal ditemukan atau tidak bisa diujicobakan oleh kode test seringkali terjadi karena DOM Tree dari tampilan HTML belum sinkron. Hal ini sangat mungkin terjadi pada aplikasi Web dengan user interface yang dibuat atau diubah oleh kode JavaScript.
Latihan Singkat: Atur Konfigurasi Test Suite BDD
Saat ini test suite BDD disiapkan untuk menjalankan test case terhadap aplikasi yang berjalan secara lokal.
Anda dapat mengubah alamat aplikasi yang akan diujicobakan dengan membuka berkas class Java SpringPetclinicHomePage
di dalam folder src/test/java/starter/navigation
.
Isi dari class tersebut saat ini adalah sebagai berikut:
1 2 3 4 5 6 7 |
|
Silakan ubah nilai string di dalam anotasi @DefaultUrl
ke alamat aplikasi anda.
Misalnya: @DefaultUrl("https://spring-petclinic-angular-[nama depan anda].dokku-ppl.cs.ui.ac.id")
.
Jika anda menjalankan aplikasi contoh Spring Petclinic secara lokal,
maka anda tidak perlu mengubah nilai string di dalam @DefaultUrl
.
Anda juga dapat mengatur apakah test suite BDD akan berjalan secara headless ataupun tidak.
Saat ini opsi headless.mode
diatur menjadi true
sehingga web browser tidak akan muncul di layar ketika test suite BDD berjalan.
Konfigurasi terkait dapat dilihat di berkas serenity.conf
dengan contoh sebagai berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Nilai di dalam opsi headless.mode
dapat diatur menjadi false
apabila ingin melihat web browser menyimulasikan interaksi dengan SUT.
Membuat Step Definition & Glue Code
Mari lihat kembali contoh skenario test "Add new specialty":
1 2 3 4 |
|
Masing-masing kalimat yang diawali dengan kata kunci Given
, When
, dan Then
perlu dipasangkan dengan serangkaian instruksi bahasa pemrograman.
Instruksi-instruksi tersebut seringkali disebut sebagai step definitions yang merupakan bagian dari Glue Code,
yaitu kode program yang mendukung dan menjalankan test suite BDD.
Sebagai contoh, mari lihat step definition padanan kalimat berawalan Given
:
1 2 3 4 5 6 7 8 9 |
|
Step definition diimplementasikan sebagai fungsi dengan informasi tambahan yang akan memetakan fungsi tersebut dengan kalimat terkait.
Pada contoh di atas, fungsi diberikan anotasi @Given
dengan parameter berisi teks regular expression (regex) yang akan dicocokkan dengan kalimat di skenario test.
Apabila kalimat pada skenario test mengandung elemen yang dapat berubah-ubah seperti aktor/pengguna fitur atau input,
maka teks regex dapat mengandung placeholder yang akan menjadi parameter bagi fungsi step definition.
Pada contoh di atas, actor
merupakan tipe parameter khusus yang disediakan templat kode untuk memetakan aktor di skenario test dengan objek Actor
yang akan dikendalikan oleh implementasi fungsi step definition.
Inti utama dari fungsi step definition adalah objek Actor
, yaitu representasi dari aktor/pengguna fitur.
Pada contoh di atas, objek Actor
memanggil fungsi wasAbleTo
yang menyimulasikan aksi-aksi aktor untuk mencapai kondisi awal yang diinginkan.
Fungsi wasAbleTo
menerima parameter berupa satu atau lebih objek Performable
yang merepresentasikan aksi fisik ketika berinteraksi dengan SUT.
Pada contoh di atas, aktor melakukan tiga aksi berikut:
- Buka web browser untuk membuka SUT, yaitu aplikasi Spring Petclinic.
- Menggerakkan kursor mouse ke tautan yang mengandung teks "Specialties"
- Klik tautan yang mengandung teks "Specialties"
Apabila ketiga aksi tersebut berhasil dilakukan, maka kondisi web browser aktor saat ini sudah menampilkan halaman daftar bidang spesialis dokter hewan. Dengan demikian, kondisi awal yang dibutuhkan untuk menguji skenario "Add new specialty" tercapai dan dapat lanjut ke aksi-aksi utama untuk menambahkan data baru.
Mari lihat step definition padanan kalimat berawalan When
:
1 2 3 4 5 6 7 8 9 |
|
Pada contoh di atas, objek Actor
memanggil fungsi attemptsTo
yang kurang lebih serupa dengan fungsi wasAbleTo
di contoh sebelumnya.
Fungsi attemptsTo
sama-sama menerima satu atau lebih objek Performable
.
Aktor melakukan tiga aksi berikut dengan asumsi saat ini aktor sedang melihat halaman daftar bidang spesialis dokter hewan:
- Klik tombol dengan teks "Add"
- Masukkan input string ke sebuah input field dengan atribut
name
atauid
bernilainame
. - Tekan tombol Enter di keyboard untuk submit input.
Hasil akhir dari ketiga aksi di atas akan diverifikasi oleh fungsi step definition yang dipetakan dengan kalimat Then
.
Contohnya adalah sebagai berikut:
1 2 3 4 5 6 7 8 9 10 |
|
Pada contoh kode di atas, objek Actor
sama-sama menggunakan fungsi attemptsTo
seperti pada fungsi step definition untuk kalimat When
.
Hanya saja, parameter fungsi tersebut sebaiknya diisi dengan objek PerformablePredicate
yang dapat dibuatkan oleh objek Ensure
.
Objek Ensure
menyediakan fungsi untuk merepresentasikan aksi verifikasi yang dilakukan oleh aktor terhadap kondisi akhir SUT.
Aksi verifikasi yang dilakukan oleh aktor adalah sebagai berikut:
- Aktor melihat seluruh input field dengan atribut
name
atauid
bernilaispec_name
. - Kemudian cek apakah nama bidang spesialis yang baru dimasukkan di antara seluruh input field yang ditemukan.
Jika aksi verifikasi berhasil dilakukan, maka test framework akan melaporkan skenario test tersebut berhasil/"pass". Sebaliknya, jika ternyata verifikasi gagal dilakukan, maka test framework akan melaporkan skenario test tersebut gagal/"fail".
Sebagai ringkasan, resep yang umum dipakai dalam membuat step definition adalah sebagai berikut:
- Step definition dari kalimat berawalan
Given
berperan untuk menyiapkan kondisi awal pada SUT sebelum menyimulasikan fitur. Kode Java yang dapat digunakan dalam implementasi step definition ini adalah fungsiwasAbleTo
milik objekActor
. Fungsi tersebut menerima parameter berupa satu atau lebih objekPerformable
yang merepresentasikan aksi aktor. Masing-masing objekPerformable
akan dijalankan sesuai dengan urutan objeknya di dalam parameter fungsiwasAbleTo
. - Step definition dari kalimat berawalan
When
berperan untuk menjalankan aksi-aksi utama yang menyimulasikan fitur. Kode Java yang dapat digunakan dalam implementasi step definition ini adalah fungsiattemptsTo
milik objekActor
. Serupa denganwasAbleTo
, fungsiattemptsTo
menerima parameter berupa satu atau lebih objekPerformable
. - Step definition dari kalimat berawalan
Then
berperan untuk melakukan verifikasi terhadap kondisi akhir pada SUT dengan kondisi yang diharapkan oleh skenario test. Kode Java yang dapat digunakan dalam implementasi step definition ini adalah fungsiattemptsTo
milik objekActor
. Hanya saja, objek-objek yang dimasukkan ke parameter fungsiattemptsTo
sebaiknya adalah objek bertipePerformablePredicate
yang dapat dibangun dengan bantuan objekEnsure
. ObjekEnsure
mengandung instruksi yang melakukan verifikasi terhadap kondisi akhir SUT.
Sebelum memulai latihan mandiri membuat step definition baru, ada baiknya kita mempelajari secara singkat bagaimana kita dapat merepresentasikan elemen-elemen user interface ke dalam kode test.
XPath
Serenity sebagai test framework sudah menyediakan library yang mempermudah pencarian elemen user interface yang umum terlibat dalam interaksi aktor dengan SUT.
Sebagai contoh, kita dapat mendapatkan referensi terhadap elemen tombol dengan teks "Add" dengan memanggil Button.withText("Add")
,
dimana fungsi tersebut akan mencari elemen HTML <button>
yang mengandung nilai teks "Add" di dalam struktur DOM Tree halaman HTML yang sedang dibuka.
Namun akan ada kasus dimana elemen user interface yang diinginkan berada di dalam struktur halaman HTML yang cukup kompleks
dan belum ada library yang dapat membantu kita menemukan elemen tersebut.
Sebagai contoh, mari lihat kode HTML untuk elemen tabel data pada halaman web fitur "Manage specialties":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
Misalkan kita ingin menyimulasikan aksi pengguna dimana pengguna menekan tombol "Edit" pada item pertama di dalam tabel.
Dapat dilihat pada potongan HTML di atas bahwa ada tiga elemen <button>
yang mengandung teks "Edit".
Bagaimana kita dapat mendapatkan referensi terhadap tombol "Edit" yang diinginkan?
Salah satu algoritma yang dapat diikuti:
- Dapatkan referensi ke elemen HTML tabel yang diinginkan dan simpan referensinya ke dalam variabel
table
. - Melalui referensi
table
, dapatkan referensi ke badan utama tabel dan simpan referensinya ke dalam variabletbody
. - Melalui referensi
tbody
, dapatkan referensi ke baris pertama tabel data dan simpan referensinya ke dalam variablerow
. - Melalui referensi
row
, dapatkan referensi ke kolom yang mengandung tombol dengan teks "Edit" dan simpan referensinya ke dalam variabelcolumn
. - Akhirnya, melalui referensi
column
, dapatkan referensi ke tombol di dalam kolom tersebut dan lakukan aksi klik pada tombol tersebut.
Algoritma di atas dapat diimplementasikan menjadi serangkaian statement pemanggilan fungsi-fungsi dari library Serenity. Namun ada alternatif lain yang lebih ringkas, yaitu menggunakan bahasa XPath. XPath adalah bahasa yang digunakan untuk menulis ekspresi yang berisi sebuah pencarian pada dokumen XML atau HTML. Instruksi pencarian elemen secara imperatif yang digambarkan pada contoh algoritma di atas dapat diringkas menjadi ekpresi singkat.
Untuk dapat menuliskan XPath, kita perlu memahami bahasanya terlebih dahulu. Terdapat beberapa referensi yang disebutkan di akhir bagian dokumen ini untuk mempelajari lebih lanjut. Namun untuk keperluan workshop singkat ini, kita dapat menggunakan shortcut yang disediakan web browser untuk mengetahui ekspresi XPath sebuah elemen pada dokumen HTML.
Buka halaman fitur "Manage specialties" dan buka Developer Tools di web browser. Pilih "Inspect Element" lalu klik tombol "Edit" agar web browser menampilkan kode HTML untuk tombol tersebut. Kemudian klik kanan kode HTML tombol tersebut, lalu piih Copy > XPath seperti yang digambarkan pada screenshot berikut:
Coba salin ("paste") ekspresi XPath ke dalam text editor untuk melihatnya. Hasilnya dapat dilihat pada teks berikut:
1 |
|
Ekspresi XPath di atas dapat diringkas menjadi:
1 |
|
Sebagai contoh penerapan XPath, lihat potongan kode berikut yang diambil dari fungsi step definition untuk mengubah nama bidang spesialis pertama pada daftar:
1 |
|
Ekspresi XPath di atas merupakan instruksi untuk mencari sebuah elemen pada dokumen HTML.
//table[@id='specialties']
mencari elemen <table>
dengan atribut id
bernilai specialties
.
Kemudian dilanjutkan dengan /tbody
yang akan mencari elemen <tbody>
yang berada di dalam <table>
.
Lalu /tr[1]/td[2]/button[1]
berarti mencari elemen <tr>
(baris) pertama di dalam tabel data,
diikuti dengan mencari elemen <td>
(kolom) kedua di baris tersebut,
dan diakhiri dengan mencari elemen <button>
(tombol) pertama di kolom tersebut.
Berikut ini adalah daftar referensi terkait XPath yang direkomendasikan:
Materi Tambahan: Troubleshooting Kegagalan Pencarian Elemen
Salah satu isu yang umum terjadi dalam pengujian aplikasi melalui simulasi interaksi dengan user interface adalah hasil eksekusi test yang tidak stabil, atau seringkali disebut sebagai flaky test. Misalnya, kadang ada sebuah test case yang sukses berjalan kemudian gagal ketika dijalankan kembali. Test yang tidak stabil bisa disebabkan karena beberapa hal, seperti isu koneksi antara web browser dengan aplikasi yang diujicobakan, atau struktur dokumen yang belum final di-update oleh kode JavaScript yang berjalan di web browser.
Beberapa isu seperti masalah koneksi memang sulit diantisipasi, sehingga solusinya terkadang cukup sekedar menjalankan test-nya kembali. Tapi terkadang ada isu yang muncul karena implementasi test yang belum komprehensif.
Ambil contoh misalnya ada sebuah test yang gagal dan laporan error yang ditangkap oleh Serenity adalah sebagai berikut:
1 |
|
Berdasarkan pesan error yang ditangkap oleh Serenity dan Selenium,
web browser yang dikendalikan oleh Selenium gagal menekan tombol pada titik koordinat (115, 717)
.
Kemungkinan besar error tersebut muncul karena secara visual tombol terkait memang tidak terlihat di dalam jendela web browser.
Oleh karena itu, instruksi di dalam fungsi step definition bisa diperbaiki untuk menjamin jendela web browser digerakkan (di-scroll) ke lokasi tombol yang diinginkan.
Sebagai contoh, mari perbaiki step definition yang dipetakan ke kalimat When {actor} adds a new specialty
sehingga web browser di-scroll ke lokasi tombol yang diinginkan sebelum menekan tombol:
1 2 3 4 5 6 7 8 9 10 |
|
Latihan Singkat: Membuat Step Definition Baru
Mari coba membuat sebuah deskripsi fitur beserta sebuah skenario test baru. Silakan ikuti tasks berikut:
- Buat class Java baru bernama
PetTypeStepDefinitions
di dalam packagestepdefinitions
. - Buat fungsi step definition yang dipetakan ke kalimat
Given
pada skenario test "Add new pet type" - Buat fungsi step definition yang dipetakan ke kalimat
When
pada skenario test "Add new pet type" - Buat fungsi step definition yang dipetakan ke kalimat
Then
pada skenario test "Add new pet type" - Jalankan test suite BDD untuk fitur "Manage pet types" dan pastikan masing-masing fungsi step definition berhasil dicocokkan dengan kalimat terkait.
Tidak ada contoh solusi untuk latihan ini karena hasil akhirnya mirip dengan fungsi-fungsi step definition untuk fitur "Manage specialties".
Silakan lihat isi class SpecialtyStepDefinitions
sebagai referensi.
Refactoring Pada Deskripsi Fitur & Glue Code
Mari lihat kembali deskripsi fitur "Manage specialties":
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Kalimat berawalan Given
muncul berulang kali pada deskripsi fitur di atas
karena masing-masing skenario test memiliki kondisi awal SUT yang sama,
yaitu aktor membuka laman daftar bidang spesialis dokter hewan.
Untuk mengurangi duplikasi dan menerapkan prinsip DRY ("Don't Repeat Yourself") pada kode test,
kita dapat menggunakan kata kunci Background
.
Background
dapat mengandung kalimat-kalimat yang akan diterapkan ke setiap skenario test di dalam deskripsi fitur.
Sebagai contoh, ubah deskripsi fitur "Manage specialties":
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Coba jalankan kembali test suite BDD dan lihat laporan hasil test.
Masing-masing skenario test akan melaporkan kalimat Given
yang sama di dalam laporannya.
Refactoring juga dapat diterapkan pada Glue Code. Sebagai contoh, mari lihat potongan kode yang menyimulasikan aksi klik menu pada navigation bar:
1 2 3 4 5 6 |
|
Aksi klik menu tersebut dapat digeneralisasi untuk digunakan kembali ketika kita akan menguji fitur lainnya yang dapat diakses melalui navigation bar yang sama.
Sebagai contoh, class Java NavigationBar
di dalam package starter.helpers
mengandung sebuah fungsi clickMenu
yang mengenkapsulasi aksi klik menu.
Contoh kode dari class tersebut dapat dilihat pada potongan kode berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Aksi klik menu pada navigation bar bisa digantikan dengan pemanggilan fungsi clickMenu
.
Cari kemunculan dua statement yang menyimulasikan aksi klik menu,
kemudian ganti dengan pemanggilan prosedur yang mengenkapsulasi aksi klik menu tersebut.
Sebagai contoh:
1 2 3 4 5 6 7 8 9 |
|
Latihan Singkat: Refactor Aksi Verifikasi Isi Daftar
Lihat kembali fungsi step definition untuk kalimat Then
fitur "Manage specialties":
1 2 3 4 5 6 7 8 9 10 |
|
Prosedur verifikasi data item pada daftar berpotensi untuk digeneralisasi sehingga dapat digunakan untuk prosedur serupa di fitur lain. Coba lakukan refactoring terhadap prosedur verifikasi tersebut dengan langkah-langkah berikut:
- Buat class Java baru dengan nama bebas di dalam package
starters.helpers
. Berikan nama class Java yang deskriptif. - Di dalam class baru tersebut, implementasikan sebuah fungsi static baru yang mengembalikan enkapsulasi prosedur verifikasi isi daftar sebagai objek tipe
PerformablePredicate
. - Ganti prosedur verifikasi di fungsi step definition terkait dengan pemanggilan fungsi yang dibuat pada langkah sebelumnya.
- Jalankan kembali test suite BDD dan pastikan hasilnya masih sama sebelum melakukan refactoring.
Contoh solusi dari fungsi yang mengandung hasil enkapsulasi adalah sebagai berikut:
1 2 3 4 5 6 7 |
|
Apabila telah selesai, simpan hasil pekerjaan. Buat commit Git dan push ke "fork" di GitLab CSUI.
Latihan Mandiri: Membuat Test Suite BDD Untuk Fitur Lainnya
Anda telah mencoba melengkapi deskripsi fitur beserta skenario test untuk dua fitur, yaitu fitur "Manage specialties" dan "Manage pet type". Masih ada beberapa fitur lain seperti fitur mengelola data dokter hewan ("Manage veterinarian"), dan fitur mengelola data pemilik binatang peliharaan ("Manage owner"). Pada waktu workshop yang tersisa, silakan lengkapi test suite BDD dengan menambahkan deskripsi fitur dan skenario test bagi fitur-fitur yang belum diuji.
Penutup
Selamat! Anda telah mencapai hari terakhir dari kegiatan workshop internal. Anda telah berlatih menerapkan otomasi kegiatan Software Quality Assurance, serta menerapkan TDD dan BDD.
Untuk bahan diskusi saat refleksi:
- Apa perbedaan test tradisional (yaitu, test yang tidak memiliki keterkaitan dengan requirements) dengan test BDD?
- Apakah hasil eksekusi test suite BDD anda stabil?
- Apa saja isu yang dapat terjadi ketika menguji SUT melalui simulasi interaksi terhadap user interface?
- Apakah BDD bisa diterapkan juga untuk menguji software dengan user interface non-visual seperti API?
Created: 2023-10-17 02:48:29