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.

  • ️ Prinsip Inti: Behavior-Driven Development (BDDD) memperluas Test-Driven Development (TDD) dengan mengekspresikan setiap skenario dalam bahasa alami yang dapat dibaca dan disetujui oleh orang yang bukan programmer.
  • 🧱 Struktur Skenario: Given menetapkan prasyarat, When melakukan tindakan, dan Then menegaskan hasilnya, sedangkan And atau But mewarisi dekorator dari langkah sebelumnya.
  • 🌐 Liputan REST: Contoh ini menjalankan perilaku CRUD penuh melalui POST, GET, PUT, dan DELETE terhadap layanan posting publik jsonplaceholder.
  • 🐍 Pengaturan Kerangka Kerja: Behave menginstal melalui pip pada Python 3 dan mengharapkan direktori fitur yang berisi file fitur ditambah paket langkah-langkah yang berisi implementasi.
  • 🔗 Pengikatan Bertahap: Decorator seperti @given, @when, dan @then cocok dengan teks fitur, dan placeholder dalam kurung kurawal meneruskan nilai dari skenario ke dalam Python fungsi.
  • ▶ ️ eksekusi: Formatter yang cantik ini mencetak hasil lulus atau gagal yang diberi kode warna untuk setiap langkah di konsol.
  • 📊 Pelaporan: Formatter allure-behave menulis hasil yang dapat dibaca mesin yang kemudian dirender oleh baris perintah Allure sebagai laporan HTML yang dapat dijelajahi.

Apa itu Pengujian BDD?

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:

  1. Transfer dana dapat dilakukan jika terdapat saldo yang cukup di rekening sumber.
  2. Transfer Dana akan dilakukan jika rincian rekening tujuan sudah benar
  3. Transfer dana akan berhasil jika kata sandi transaksi / kode RSA / otentikasi keamanan yang dimasukkan oleh pengguna benar.
  4. Transfer dana harus tetap dilakukan meskipun sedang hari libur bank.
  5. 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:

Pengaturan Proyek:

  • Buat proyek baru
  • Buat struktur direktori berikut ini

Pengaturan Proyek

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:

Pengaturan Proyek

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:

Langkah Implementasi

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:

Menjalankan Tes

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

Laporan Uji dalam Format HTML

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.

  1. 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.
  2. 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.
  3. Pindahkan pengaturan bersama ke latar belakang. Contoh di atas menggunakan Background: Given I set sample REST API url sehingga setiap skenario mewarisi basisnya URL tanpa mengulanginya.
  4. 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.
  5. 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.
  6. 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.
  7. 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. context Objek tersebut memastikan statusnya kembali normal dengan rapi antar skenario.
  8. Beri tag pada skenario untuk eksekusi selektif. Tag seperti @smoke or @regression mengizinkan behave --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.

Pertanyaan Umum Demo Slot

Keduanya membaca berkas fitur Gherkin. Cucumber mengikat langkah-langkah ke Java, Ruby, atau JavaScript, sedangkan Behave mengikatnya ke PythonPilih yang sesuai dengan tumpukan aplikasi Anda sehingga definisi langkah menggunakan kembali utilitas pengujian yang sudah ada.

Ya. Behave mengembalikan kode keluar bukan nol ketika skenario apa pun gagal, jadi JenkinsGitLab CI, atau GitHub Actions dapat secara otomatis menggagalkan build. Publikasikan folder hasil Allure sebagai artefak build untuk pelaporan.

Ya. AI Para asisten menyusun skenario Given-When-Then dari user story atau spesifikasi OpenAPI. RevLihat output untuk kasus negatif dan aturan bisnis yang hilang, karena skenario yang dihasilkan sering kali hanya mencakup skenario yang berhasil (happy path).

Alat AI mendeteksi skenario duplikat atau hampir duplikat, menyarankan langkah-langkah berparameter yang dapat digunakan kembali, dan mengelompokkan kegagalan yang tidak stabil berdasarkan kemungkinan penyebabnya. Hal ini mengurangi upaya audit manual seiring bertambahnya jumlah file fitur di berbagai tim.

Ambil token sekali di hook before_all pada environment.py, simpan di objek konteks, dan lampirkan sebagai header Otorisasi di setiap langkah permintaan. Simpan kredensial dalam variabel lingkungan, jangan pernah di file fitur.

Ringkaslah postingan ini dengan: