Apa itu Pengujian BDD? Kerangka Kerja Pengembangan Berbasis Perilaku (Behaviour-Driven Development Framework)
⚡ Ringkasan Cerdas
Pengujian BDD menjelaskan perilaku aplikasi dalam bahasa Given-When-Then yang sederhana sehingga analis, pengembang, dan penguji dapat berbagi satu spesifikasi. Panduan ini menerapkan pendekatan tersebut untuk pengujian REST API dengan Behave, sebuah platform yang mendukung BDD Testing. Python kerangka kerja, yang mencakup pengaturan, file fitur, implementasi langkah, eksekusi, dan pelaporan.

Apa itu Pengujian BDD (Perkembangan Berbasis Perilaku)?
Pengujian BDD (Pengembangan berbasis perilaku). BDD adalah teknik pengembangan perangkat lunak tangkas dan merupakan perluasan dari TDD, yaitu Pengembangan Berbasis Pengujian (Test Driven Development). Dalam BDD, kasus uji ditulis dalam bahasa alami yang bahkan orang yang bukan programmer pun dapat membacanya.
Bagaimana Pengujian BDD bekerja?
Bayangkan Anda ditugaskan untuk membuat modul Transfer Dana dalam aplikasi Perbankan Online.
Ada beberapa cara untuk mengujinya:
- Transfer dana dapat dilakukan jika terdapat saldo yang cukup di rekening sumber.
- Transfer Dana akan dilakukan jika rincian rekening tujuan sudah benar
- Transfer dana akan berhasil jika kata sandi transaksi / kode RSA / otentikasi keamanan yang dimasukkan oleh pengguna benar.
- Transfer dana harus tetap dilakukan meskipun sedang hari libur bank.
- Transfer Dana harus dilakukan pada tanggal yang akan datang sebagaimana ditentukan oleh pemegang rekening
The Skenario Uji menjadi lebih rumit dan kompleks ketika kita mempertimbangkan fitur tambahan seperti mentransfer sejumlah X untuk jangka waktu Y hari atau bulan, berhenti.ping transfer terjadwal ketika totalnya mencapai Z, dan seterusnya.
Kecenderungan umum para pengembang adalah mengembangkan fitur terlebih dahulu dan menulis kode pengujian kemudian. Seperti yang terlihat pada kasus di atas, Uji Kasus Pengembangan di sini kompleks, jadi pengembang akan menundanya. pengujian hingga dirilis, di mana pengujian cepat namun tidak efektif dilakukan.
Untuk mengatasi masalah ini, Behavior Driven Development (BDD) diciptakan. BDD membuat seluruh proses pengujian lebih mudah bagi pengembang.
Di BDD, apapun yang Anda tulis harus masuk Diberikan-Kapan-Lalu langkah-langkah. Mari kita pertimbangkan contoh yang sama di atas dalam BDD:
Given that a fund transfer module in net banking application has been developed And I am accessing it with proper authentication When I shall transfer with enough balance in my source account Or I shall transfer on a Bank Holiday Or I shall transfer on a future date And destination a/c details are correct And transaction password / rsa code / security authentication for the transaction is correct And press or click send button Then amount must be transferred And the event will be logged in log file
Formulir ini mudah ditulis, dibaca, dan dipahami. Formulir ini mencakup setiap kemungkinan kasus uji untuk modul transfer dana dan dapat dimodifikasi dengan cepat untuk mengakomodasi lebih banyak kasus uji. Formulir ini juga seperti dokumentasi yang selalu diperbarui untuk modul tersebut. Karena BDD berkembang dari TDD, perbedaan antara keduanya perlu dipahami terlebih dahulu sebelum beralih ke pembuatan alat bantu.
BDD vs TDD: Perbedaan Utama
Kedua praktik tersebut mengutamakan pengujian, dan keduanya mempersingkat siklus umpan balik. Perbedaannya terletak pada siapa yang menulis pengujian, bahasa apa yang digunakan dalam pengujian tersebut, dan lapisan aplikasi mana yang mereka uraikan.
| Aspek | TDD (Pengembangan Berbasis Pengujian) | BDD (Perkembangan Berbasis Perilaku) |
|---|---|---|
| Fokus | Bagaimana cara kerja internal sebuah unit kode | Bagaimana sistem berperilaku dari perspektif pengguna |
| Bahasa | Pernyataan dalam bahasa pemrograman | Skenario Given-When-Then dalam bahasa alami |
| Penulis utama | Pengembang | Analis bisnis, pemilik produk, penguji, dan pengembang bersama-sama |
| Readable oleh orang yang bukan programmer | Tidak | Ya |
| Ruang lingkup tipikal | Tingkat unit | Fitur, API, dan tingkat penerimaan |
| Alat umum | JUnit, pytest, NUnit | Berperilaku baik, Cucumber, SpecFlow, JBehave |
Keduanya saling melengkapi dan bukan bersaing. Tim umumnya mempertahankan hal tersebut. TDD untuk desain tingkat unit dan tambahkan skenario BDD di atasnya untuk menggambarkan perilaku yang sebenarnya disetujui oleh pemangku kepentingan. Karena endpoint REST berada tepat di lapisan penerimaan tersebut, maka endpoint REST sangat cocok untuk BDD.
Apa itu Pengujian REST API?
Karena REST telah menjadi gaya populer untuk membangun API, mengotomatiskan kasus uji API REST bersamaan dengan kasus uji UI menjadi sama pentingnya. REST Pengujian API Melibatkan pengujian aksi CRUD (Create-Read-Update-Delete) dengan metode POST, GET, PUT, dan DELETE secara berturut-turut.
Apa itu Berperilaku?
Berperilaku adalah salah satu yang populer Python Kerangka kerja pengujian BDD. Berikut cara kerja Behave:
- Berkas fitur ditulis oleh Analis Bisnis, Sponsor, atau siapa pun yang bertanggung jawab atas skenario perilaku tersebut. Berkas fitur menggunakan format bahasa alami yang menjelaskan suatu fitur, atau bagian dari suatu fitur, dengan contoh representatif dari hasil yang diharapkan.
- Langkah-langkah skenario ini dipetakan ke implementasi langkah yang ditulis dalam Python.
- Secara opsional, kontrol lingkungan menjalankan kode sebelum dan sesudah langkah, skenario, fitur, atau seluruh proses.
Setelah peran masing-masing file dipahami dengan jelas, kerangka kerja tersebut sekarang dapat diinstal.
Menyiapkan Kerangka Pengujian BDD Berperilaku Windows
instalasi:
- Download dan menginstal Python 3 dari https://www.python.org/
- Jalankan perintah berikut di command prompt untuk menginstal Behave.
pip install behave- ide: PyCharm Edisi Komunitas digunakan di sini — https://www.jetbrains.com/pycharm/download/
Pengaturan Proyek:
- Buat proyek baru
- Buat struktur direktori berikut ini
Tangkapan layar di atas menunjukkan tata letak yang diharapkan oleh Behave: sebuah fitur direktori yang menyimpan file fitur, dan bersarang tangga direktori yang memuat Python implementasi. Behave menemukan keduanya berdasarkan nama, jadi nama folder harus sama persis.
File Fitur:
Sekarang mari kita buat file fiturnya. Sample_REST_API_Testing.fitur, dengan fitur berupa operasi CRUD pada layanan 'posts'.
Contoh ini menggunakan https://jsonplaceholder.typicode.com/ Situs ini memposting contoh layanan REST, sebuah API palsu gratis yang menerima permintaan tulis dan mengembalikan respons realistis tanpa menyimpan perubahan.
Contoh skenario POST
Scenario: POST post example -> creating a new post item using the 'posts' service Given I set post posts API endpoint -> prerequisite: sets the URL of the posts service When I set HEADER param request content type as "application/json" And set request body And send POST HTTP request -> the actual test step Then I receive valid HTTP response code 201 And Response body "POST" is non-empty -> verification of the response body
Demikian pula, Anda dapat menulis skenario yang tersisa sebagai berikut:
Sample_REST_API_Testing.fitur
Feature: Test CRUD methods in Sample REST API testing framework Background: Given I set sample REST API url Scenario: POST post example Given I Set POST posts api endpoint When I Set HEADER param request content type as "application/json" And Set request Body And Send a POST HTTP request Then I receive valid HTTP response code 201 And Response BODY "POST" is non-empty Scenario: GET posts example Given I Set GET posts api endpoint "1" When I Set HEADER param request content type as "application/json" And Send GET HTTP request Then I receive valid HTTP response code 200 for "GET" And Response BODY "GET" is non-empty Scenario: UPDATE posts example Given I Set PUT posts api endpoint for "1" When I Set Update request Body And Send PUT HTTP request Then I receive valid HTTP response code 200 for "PUT" And Response BODY "PUT" is non-empty Scenario: DELETE posts example Given I Set DELETE posts api endpoint for "1" When I Send DELETE HTTP request Then I receive valid HTTP response code 200 for "DELETE"
Langkah Implementasi
Sekarang, untuk langkah-langkah fitur yang digunakan dalam skenario di atas, Anda dapat menulis implementasinya di Python berkas-berkas di dalam direktori “steps”.
Kerangka kerja Behave mengidentifikasi fungsi langkah dengan mencocokkan decorator dengan predikat file fitur. Misalnya, sebuah Mengingat Predikat dalam skenario berkas fitur mencari fungsi langkah yang membawa @given Dekorator. Pencocokan yang sama terjadi untuk Ketika ke KemudianDalam kasus 'But' dan 'And', fungsi langkah menggunakan dekorator yang sama dengan langkah sebelumnya. Misalnya, jika 'And' mengikuti Given, dekorator fungsi langkah yang sesuai adalah @given.
Sebagai contoh, langkah "When" untuk POST dapat diimplementasikan sebagai berikut. Perhatikan bagaimana "application/json" Data tersebut diteruskan dari file fitur ke dalam placeholder yang diapit tanda kurung kurawal — ini disebut parameterisasi.
# Decorator: the braced name captures a value from the feature file @when(u'I Set HEADER param request content type as "{header_content_type}"') def step_impl(context, header_content_type): # Step implementation: set the content type on the request header request_headers['Content-Type'] = header_content_type
Demikian pula, implementasi langkah-langkah lainnya pada tahapan tersebut. Python berkasnya akan terlihat seperti ini:
sample_step_implementation.py
from behave import given, when, then, step import requests api_endpoints = {} request_headers = {} response_codes = {} response_texts = {} request_bodies = {} api_url = None @given(u'I set sample REST API url') def step_impl(context): global api_url api_url = 'https://jsonplaceholder.typicode.com' # START POST Scenario @given(u'I Set POST posts api endpoint') def step_impl(context): api_endpoints['POST_URL'] = api_url + '/posts' print('url :' + api_endpoints['POST_URL']) @when(u'I Set HEADER param request content type as "{header_content_type}"') def step_impl(context, header_content_type): request_headers['Content-Type'] = header_content_type # "And" or "But" steps are renamed by behave to match their preceding step @when(u'Set request Body') def step_impl(context): request_bodies['POST'] = {"title": "foo", "body": "bar", "userId": "1"} @when(u'Send POST HTTP request') def step_impl(context): # send the request and save the response object response = requests.post(url=api_endpoints['POST_URL'], json=request_bodies['POST'], headers=request_headers) response_texts['POST'] = response.text print("post response :" + response.text) response_codes['POST'] = response.status_code @then(u'I receive valid HTTP response code 201') def step_impl(context): print('Post rep code ;' + str(response_codes['POST'])) assert response_codes['POST'] == 201 # END POST Scenario # START GET Scenario @given(u'I Set GET posts api endpoint "{id}"') def step_impl(context, id): api_endpoints['GET_URL'] = api_url + '/posts/' + id print('url :' + api_endpoints['GET_URL']) @when(u'Send GET HTTP request') def step_impl(context): response = requests.get(url=api_endpoints['GET_URL'], headers=request_headers) response_texts['GET'] = response.text response_codes['GET'] = response.status_code @then(u'I receive valid HTTP response code 200 for "{request_name}"') def step_impl(context, request_name): print('Get rep code for ' + request_name + ':' + str(response_codes[request_name])) assert response_codes[request_name] == 200 @then(u'Response BODY "{request_name}" is non-empty') def step_impl(context, request_name): print('request_name: ' + request_name) print(response_texts) assert response_texts[request_name] is not None # END GET Scenario # START PUT/UPDATE @given(u'I Set PUT posts api endpoint for "{id}"') def step_impl(context, id): api_endpoints['PUT_URL'] = api_url + '/posts/' + id print('url :' + api_endpoints['PUT_URL']) @when(u'I Set Update request Body') def step_impl(context): request_bodies['PUT'] = {"title": "foo", "body": "bar", "userId": "1", "id": "1"} @when(u'Send PUT HTTP request') def step_impl(context): response = requests.put(url=api_endpoints['PUT_URL'], json=request_bodies['PUT'], headers=request_headers) response_texts['PUT'] = response.text print("update response :" + response.text) response_codes['PUT'] = response.status_code # END PUT/UPDATE # START DELETE @given(u'I Set DELETE posts api endpoint for "{id}"') def step_impl(context, id): api_endpoints['DELETE_URL'] = api_url + '/posts/' + id print('url :' + api_endpoints['DELETE_URL']) @when(u'I Send DELETE HTTP request') def step_impl(context): response = requests.delete(url=api_endpoints['DELETE_URL']) response_texts['DELETE'] = response.text print("DELETE response :" + response.text) response_codes['DELETE'] = response.status_code # END DELETE
⚠️ Catatan: Membandingkan kode status dengan == daripada is hal-hal penting. Yang is Operator menguji identitas objek, bukan kesamaan, dan Python 3.8 dan kemudian menaikkan Peringatan Sintaksis: “is” dengan literal untuk pola itu. Pernyataan apa pun yang ditulis sebagai assert code is 201 harus ditulis ulang sebagai assert code == 201.
Menjalankan Tes
Pengembangan skrip pengujian telah selesai, jadi mari kita jalankan pengujiannya. Jalankan perintah berikut di command prompt untuk menjalankan file fitur:
:: Run a single feature file with the pretty formatter behave -f pretty features\feature_files_folder\Sample_REST_API_Testing.feature :: Run every feature in the project behave
Ini menampilkan hasil eksekusi pengujian sebagai berikut:
Tampilan laporan di konsol
Output konsol memang praktis selama pengembangan, tetapi pemangku kepentingan biasanya lebih menyukai laporan yang mudah dibaca, yang disediakan oleh Allure.
Laporan
Pertama, instal formatter Allure Behave dan alat baris perintah Allure. Formatter tersebut adalah sebuah Python paket; alat baris perintah merupakan unduhan terpisah yang dijelaskan di dalam Dokumentasi Laporan Allure.
:: 1. Install the formatter pip install allure-behave :: 2. Run the tests and write raw results to a folder behave -f allure_behave.formatter:AllureFormatter -o reports/allure-results features/ :: 3. Render and open the HTML report allure serve reports/allure-results
Ini menghasilkan laporan hasil tes dalam format yang mudah dipahami dan informatif seperti ini:
Laporan Uji dalam Format HTML
Laporan Uji menampilkan hasil Skenario individual
Suatu rangkaian fitur yang berfungsi hanya berguna jika tetap mudah dibaca seiring berkembangnya API, dan di sinilah disiplin dalam mengelola file fitur membuahkan hasil.
Praktik Terbaik untuk Menulis File Fitur Behave
Rangkaian fitur Behave akan cepat menurun kualitasnya ketika skenario menggambarkan klik dan muatan data, bukan perilaku. Praktik-praktik di bawah ini menjaga agar file fitur tetap mudah dibaca oleh pemangku kepentingan bisnis sekaligus menjaga agar...ping itu Python lapisan yang dapat dipelihara oleh para insinyur.
- Jelaskan perilaku, bukan implementasi. Tuliskan “Dengan asumsi pelanggan memiliki saldo yang cukup”, bukan “Dengan asumsi kolom saldo sama dengan 500”. File fitur menyatakan apa yang dilakukan sistem; file langkah menyatakan bagaimana hal itu diperiksa.
- Pertahankan satu perilaku untuk setiap skenario. Skenario yang menyatakan kode status, isi respons, dan baris basis data sebenarnya terdiri dari tiga skenario. Memisahkan ketiganya membuat kegagalan langsung mengarah pada penyebabnya.
- Pindahkan pengaturan bersama ke latar belakang. Contoh di atas menggunakan
Background: Given I set sample REST API urlsehingga setiap skenario mewarisi basisnya URL tanpa mengulanginya. - Gunakan parameterisasi daripada menduplikasi. Placeholder yang diberi tanda kurung seperti
"{request_name}"Biarkan satu fungsi langkah melayani pernyataan GET, PUT, dan DELETE, itulah sebabnya contoh ini membutuhkan definisi langkah yang jauh lebih sedikit daripada skenario. - Gunakan Garis Besar Skenario untuk variasi data. Ketika perilaku yang sama harus dibuktikan untuk beberapa input, sebuah
Examples:Tabel lebih jelas daripada skenario yang disalin. - Hindari ketergantungan antar skenario. Behave tidak menjamin bahwa skenario POST akan berjalan sebelum skenario GET dalam setiap konfigurasi. Setiap skenario harus menciptakan status yang dibutuhkannya.
- Gantikan variabel global tingkat modul dengan konteks. Contoh ini menyimpan endpoint dan respons dalam kamus modul untuk mempersingkat kode. Dalam rangkaian produksi, simpanlah di Behave.
contextObjek tersebut memastikan statusnya kembali normal dengan rapi antar skenario. - Beri tag pada skenario untuk eksekusi selektif. Tag seperti
@smokeor@regressionmengizinkanbehave --tags=@smoke, yang menjaga agar umpan balik dalam alur kerja tetap cepat.
Menerapkan kebiasaan ini sejak file fitur pertama akan menjaga nilai rangkaian BDD jauh melampaui contoh CRUD awal. Tim yang memperluas pendekatan ini lebih jauh sering kali menggabungkannya dengan Cucumber untuk proyek JVM atau Postman untuk pemeriksaan API eksploratif.






