BDD Testing คืออะไร? กรอบการพัฒนาแบบเน้นพฤติกรรม (Behaviour-Driven Development Framework)

⚡ สรุปอย่างชาญฉลาด

การทดสอบแบบ BDD อธิบายพฤติกรรมของแอปพลิเคชันด้วยภาษา Given-When-Then ที่เรียบง่าย เพื่อให้นักวิเคราะห์ นักพัฒนา และผู้ทดสอบใช้ข้อกำหนดเดียวกัน บทความนี้จะนำแนวทางดังกล่าวมาใช้กับการทดสอบ REST API โดยใช้ Behave ซึ่งเป็นเครื่องมือทดสอบ REST API Python กรอบการทำงานที่ครอบคลุมการตั้งค่า ไฟล์คุณลักษณะ การใช้งานตามขั้นตอน การดำเนินการ และการรายงาน

  • 🗣️ หลักการสำคัญ: การพัฒนาแบบเน้นพฤติกรรม (Behavior-Driven Development) เป็นการต่อยอดจากการพัฒนาแบบเน้นการทดสอบ (Test-Driven Development) โดยการนำเสนอทุกสถานการณ์ในรูปแบบภาษาธรรมชาติที่ผู้ที่ไม่ใช่โปรแกรมเมอร์สามารถอ่านและอนุมัติได้
  • 🧱 โครงสร้างของสถานการณ์จำลอง: Given กำหนดเงื่อนไขเบื้องต้น, When ดำเนินการตามการกระทำ, และ Then ยืนยันผลลัพธ์ ในขณะที่ And หรือ But สืบทอดตัวตกแต่งจากขั้นตอนก่อนหน้า
  • 🌐 ความครอบคลุมของ REST: ตัวอย่างนี้แสดงการทำงานแบบ CRUD อย่างเต็มรูปแบบผ่าน POST, GET, PUT และ DELETE กับบริการโพสต์ jsonplaceholder สาธารณะ
  • 🐍 การตั้งค่าเฟรมเวิร์ก: ติดตั้ง Behave ผ่าน pip บน Python 3 และคาดหวังว่าจะมีไดเร็กทอรี features ที่ประกอบด้วยไฟล์ฟีเจอร์ รวมถึงแพ็กเกจ steps ที่เก็บการใช้งานต่างๆ
  • 🔗 การผูกแบบขั้นบันได: ตัวตกแต่ง เช่น @given, @when และ @then จะตรงกับข้อความคุณลักษณะ และตัวยึดตำแหน่งแบบวงเล็บปีกกาจะส่งผ่านค่าจากสถานการณ์ไปยัง Python ฟังก์ชัน
  • ▶️ การดำเนินการ: โปรแกรมจัดรูปแบบที่สวยงามจะพิมพ์ผลลัพธ์ผ่านหรือล้มเหลวโดยใช้รหัสสีสำหรับแต่ละขั้นตอนลงในคอนโซล
  • 📊 รายงาน: ตัวจัดรูปแบบ allure-behave จะเขียนผลลัพธ์ที่เครื่องอ่านได้ ซึ่งบรรทัดคำสั่ง Allure จะแสดงผลออกมาเป็นรายงาน HTML ที่สามารถเรียกดูได้

การทดสอบ BDD คืออะไร

การทดสอบ BDD (การพัฒนาพฤติกรรมขับเคลื่อน) คืออะไร?

การทดสอบ BDD (การพัฒนาที่ขับเคลื่อนด้วยพฤติกรรม) BDD (Behavior-Driven Development) เป็นเทคนิคการพัฒนาซอฟต์แวร์แบบ Agile และเป็นส่วนขยายของ TDD (Test Driven Development) หรือการพัฒนาแบบเน้นการทดสอบ ใน BDD นั้น กรณีทดสอบจะเขียนด้วยภาษาธรรมชาติที่แม้แต่ผู้ที่ไม่ใช่โปรแกรมเมอร์ก็สามารถอ่านได้

การทดสอบ BDD ทำงานอย่างไร

สมมติว่าคุณได้รับมอบหมายให้สร้างโมดูลโอนเงินในแอปพลิเคชันธนาคารออนไลน์

มีหลายวิธีในการทดสอบ:

  1. การโอนเงินควรดำเนินการได้ก็ต่อเมื่อมีเงินคงเหลือในบัญชีต้นทางเพียงพอ
  2. การโอนเงินควรเกิดขึ้นหากรายละเอียดบัญชีปลายทางถูกต้อง
  3. การโอนเงินจะดำเนินการได้หากรหัสผ่านการทำธุรกรรม / รหัส RSA / การตรวจสอบความปลอดภัยที่ผู้ใช้ป้อนถูกต้อง
  4. การโอนเงินควรดำเนินการต่อไปแม้ว่าจะเป็นวันหยุดธนาคารก็ตาม
  5. การโอนเงินควรเกิดขึ้นในอนาคตตามที่เจ้าของบัญชีกำหนด

การขอ สถานการณ์ทดสอบ จะมีความซับซ้อนมากขึ้นเมื่อเราพิจารณาคุณสมบัติเพิ่มเติม เช่น การโอนเงินจำนวน X ในช่วงเวลา Y วันหรือเดือน การหยุดping การโอนเงินตามกำหนดเวลาเมื่อยอดรวมถึง Z และอื่นๆ

โดยทั่วไปแล้ว นักพัฒนาซอฟต์แวร์มักจะพัฒนาฟีเจอร์ต่างๆ ก่อน แล้วค่อยเขียนโค้ดทดสอบในภายหลัง ดังที่เห็นได้จากกรณีข้างต้น กรณีทดสอบ การพัฒนาในพื้นที่นี้มีความซับซ้อน ดังนั้นผู้พัฒนาจึงจะเลื่อนกำหนดการออกไป การทดสอบ จนกว่าจะถึงวันวางจำหน่าย ซึ่งในขั้นตอนนี้จะมีการทดสอบอย่างรวดเร็วแต่ไม่มีประสิทธิภาพ

เพื่อแก้ไขปัญหาดังกล่าว จึงได้มีการคิดค้น Behavior Driven Development (BDD) ขึ้นมา ซึ่งทำให้กระบวนการทดสอบทั้งหมดง่ายขึ้นสำหรับนักพัฒนา

ใน BDD สิ่งที่คุณเขียนจะต้องเข้าไปอยู่ในนั้น ให้-เมื่อ-แล้ว ขั้นตอนต่างๆ ลองพิจารณาตัวอย่างเดียวกันข้างต้นในรูปแบบ 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

แบบฟอร์มนี้เขียนง่าย อ่านง่าย และเข้าใจง่าย ครอบคลุมทุกกรณีทดสอบที่เป็นไปได้สำหรับโมดูลการโอนเงิน และสามารถปรับเปลี่ยนได้อย่างรวดเร็วเพื่อรองรับกรณีทดสอบเพิ่มเติม นอกจากนี้ยังอ่านง่ายเหมือนเอกสารประกอบการใช้งานโมดูลที่มีการปรับปรุงอยู่เสมอ เนื่องจาก BDD พัฒนามาจาก TDD ความแตกต่างระหว่างทั้งสองจึงควรทำความเข้าใจให้ชัดเจนก่อนที่จะก้าวไปสู่การใช้งานเครื่องมือ

BDD กับ TDD: ความแตกต่างที่สำคัญ

ทั้งสองวิธีเน้นการทดสอบก่อน และช่วยลดระยะเวลาในการได้รับผลตอบรับ ความแตกต่างอยู่ที่ผู้เขียนการทดสอบ ภาษาที่ใช้ในการทดสอบ และส่วนใดของแอปพลิเคชันที่ถูกทดสอบ

แง่มุม TDD (การพัฒนาแบบขับเคลื่อนด้วยการทดสอบ) BDD (การพัฒนาที่ขับเคลื่อนด้วยพฤติกรรม)
โฟกัส วิธีการทำงานภายในของหน่วยโค้ด ระบบทำงานอย่างไรในมุมมองของผู้ใช้
ภาษาที่ใช้ การยืนยันภาษาการเขียนโปรแกรม สถานการณ์ Given-When-Then ในภาษาธรรมชาติ
ผู้เขียนหลัก ผู้พัฒนา นักวิเคราะห์ธุรกิจ เจ้าของผลิตภัณฑ์ ผู้ทดสอบ และนักพัฒนาซอฟต์แวร์ ทำงานร่วมกัน
Readable โดยผู้ที่ไม่ใช่โปรแกรมเมอร์ ไม่ มี (ใบกำกับภาษีเต็มรูปแบบ)
ขอบเขตทั่วไป ระดับหน่วย คุณสมบัติ, API และระดับการยอมรับ
เครื่องมือทั่วไป JUnitpytest, NUnit ประพฤติ, CucumberSpecFlow, JBehave

ทั้งสองอย่างเป็นสิ่งที่ส่งเสริมซึ่งกันและกันมากกว่าที่จะแข่งขันกัน โดยทั่วไปแล้วทีมต่างๆ มักจะรักษาไว้ซึ่งสิ่งต่างๆ เหล่านี้ TDD สำหรับการออกแบบในระดับหน่วย และเพิ่มสถานการณ์ BDD เข้าไปเพื่ออธิบายพฤติกรรมที่ผู้มีส่วนได้ส่วนเสียอนุมัติจริง ๆ เนื่องจาก REST endpoint อยู่ในระดับการยอมรับนั้นพอดี จึงเหมาะสมอย่างยิ่งสำหรับ BDD

การทดสอบ REST API คืออะไร

เนื่องจาก REST ได้กลายเป็นรูปแบบที่ได้รับความนิยมในการสร้าง API การทดสอบ REST API แบบอัตโนมัติจึงมีความสำคัญไม่แพ้กันเมื่อเทียบกับการทดสอบ UI การทดสอบ API เกี่ยวข้องกับการทดสอบการดำเนินการ CRUD (สร้าง-อ่าน-อัปเดต-ลบ) ด้วยวิธีการ POST, GET, PUT และ DELETE ตามลำดับ

ประพฤติคืออะไร?

ประพฤติเป็นหนึ่งในความนิยม Python เฟรมเวิร์กการทดสอบ BDD ต่อไปนี้คือวิธีการทำงานของฟังก์ชัน:

  • ไฟล์รายละเอียดคุณลักษณะ (Feature file) เขียนโดยนักวิเคราะห์ธุรกิจ ผู้สนับสนุน หรือผู้รับผิดชอบสถานการณ์พฤติกรรมต่างๆ ไฟล์รายละเอียดคุณลักษณะใช้รูปแบบภาษาธรรมชาติในการอธิบายคุณลักษณะ หรือส่วนหนึ่งของคุณลักษณะ พร้อมตัวอย่างที่แสดงถึงผลลัพธ์ที่คาดหวัง
  • ขั้นตอนสถานการณ์เหล่านี้ถูกแมปเข้ากับการดำเนินการตามขั้นตอนที่เขียนไว้ใน Python.
  • นอกจากนี้ ระบบควบคุมสภาพแวดล้อมยังสามารถรันโค้ดก่อนและหลังขั้นตอน สถานการณ์ คุณสมบัติ หรือการทำงานทั้งหมดได้อีกด้วย

เมื่อเข้าใจบทบาทของแต่ละไฟล์อย่างชัดเจนแล้ว ขั้นตอนต่อไปคือการติดตั้งเฟรมเวิร์ก

การตั้งค่า BDD Testing Framework ทำงาน Windows

การติดตั้ง:

  • ดาวน์โหลดและติดตั้ง Python 3 จาก https://www.python.org/
  • เรียกใช้คำสั่งต่อไปนี้ที่พรอมต์คำสั่งเพื่อติดตั้ง Behave
  • pip install behave
  • ไอดี: PyCharm ในที่นี้ใช้ Community Edition — https://www.jetbrains.com/pycharm/download/

การตั้งค่าโครงการ:

  • สร้างโครงการใหม่
  • สร้างโครงสร้างไดเร็กทอรีดังต่อไปนี้

ตั้งค่าโครงการ

ภาพหน้าจอข้างต้นแสดงเค้าโครงที่ Behave คาดหวัง: a ที่ ไดเร็กทอรีที่เก็บไฟล์ฟีเจอร์ และไดเร็กทอรีย่อยที่ซ้อนกัน ทำตามขั้นตอน ไดเร็กทอรีที่เก็บ Python การใช้งาน Behave ค้นหาทั้งสองอย่างโดยใช้ชื่อ ดังนั้นชื่อโฟลเดอร์ต้องตรงกันทุกประการ

ไฟล์คุณสมบัติ:

ต่อไปเรามาสร้างไฟล์ฟีเจอร์กันเถอะ Sample_REST_API_Testing.featureโดยมีคุณสมบัติหลักคือการดำเนินการ CRUD บนบริการ 'โพสต์'

ตัวอย่างนี้ใช้ https://jsonplaceholder.typicode.com/ บทความนี้เสนอตัวอย่างบริการ REST ซึ่งเป็น API จำลองฟรี ที่รับคำขอเขียนและส่งคืนการตอบสนองที่สมจริงโดยไม่บันทึกการเปลี่ยนแปลง

ตัวอย่างสถานการณ์ 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

ในทำนองเดียวกัน คุณสามารถเขียนสถานการณ์ที่เหลือได้ดังนี้:

ตั้งค่าโครงการ

Sample_REST_API_Testing.feature

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"

ขั้นตอนการดำเนินการ

สำหรับขั้นตอนการทำงานที่ใช้ในสถานการณ์ข้างต้น คุณสามารถเขียนการใช้งานได้ดังนี้ Python ไฟล์ต่างๆ ภายในไดเร็กทอรี “steps”

เฟรมเวิร์ก Behave ระบุฟังก์ชันขั้นตอนโดยการจับคู่ตัวตกแต่งกับเงื่อนไขในไฟล์คุณลักษณะ ตัวอย่างเช่น ให้ เงื่อนไขในสถานการณ์ไฟล์คุณลักษณะจะค้นหาฟังก์ชันขั้นบันไดที่บรรจุ @given นักตกแต่ง การจับคู่แบบเดียวกันนี้เกิดขึ้นสำหรับ เมื่อ และ แล้วก็ในกรณีของ 'But' และ 'And' ฟังก์ชันขั้นตอนจะใช้ตัวตกแต่ง (decorator) เดียวกันกับขั้นตอนก่อนหน้า ตัวอย่างเช่น ถ้า 'And' ตามหลัง Given ตัวตกแต่งฟังก์ชันขั้นตอนที่ตรงกันคือ @given.

ตัวอย่างเช่น ขั้นตอน "เมื่อไร" สำหรับ POST สามารถนำไปใช้ได้ดังนี้ โปรดสังเกตวิธีการ "application/json" จะถูกส่งผ่านจากไฟล์คุณลักษณะไปยังตัวยึดตำแหน่งที่มีวงเล็บ — ซึ่งเรียกว่าการกำหนดพารามิเตอร์

# 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

ในทำนองเดียวกัน การดำเนินการตามขั้นตอนอื่นๆ ในขั้นตอนนี้ Python ไฟล์จะมีลักษณะดังนี้:

ขั้นตอนการดำเนินการ

ตัวอย่าง_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

⚠️หมายเหตุ: การเปรียบเทียบรหัสสถานะกับ == มากกว่า is เรื่องราวต่างๆ is ตัวดำเนินการจะทดสอบเอกลักษณ์ของวัตถุ ไม่ใช่ความเท่าเทียมกัน และ Python 3.8 และต่อมาก็เพิ่มขึ้น SyntaxWarning: “is” with a literal สำหรับรูปแบบนั้น ข้อความยืนยันใดๆ ที่เขียนไว้ดังนี้ assert code is 201 ควรเขียนใหม่เป็น assert code == 201.

ดำเนินการทดสอบ

การพัฒนาสคริปต์ทดสอบเสร็จสมบูรณ์แล้ว ดังนั้นเรามาทำการทดสอบกัน เรียกใช้ไฟล์ฟีเจอร์โดยใช้คำสั่งต่อไปนี้ที่พรอมต์คำสั่ง:

:: 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

ผลลัพธ์ของการทดสอบจะแสดงดังต่อไปนี้:

ดำเนินการทดสอบ

รายงานการแสดงผลบนคอนโซล

การแสดงผลข้อมูลผ่านคอนโซลนั้นสะดวกในระหว่างการพัฒนา แต่โดยทั่วไปแล้วผู้มีส่วนได้ส่วนเสียมักต้องการรายงานที่อ่านง่าย ซึ่ง Allure ก็สามารถมอบให้ได้

รายงาน

ขั้นแรก ติดตั้งโปรแกรมจัดรูปแบบ Allure Behave และเครื่องมือบรรทัดคำสั่ง Allure โปรแกรมจัดรูปแบบนี้คือ... Python แพ็คเกจ; เครื่องมือบรรทัดคำสั่งเป็นไฟล์ดาวน์โหลดแยกต่างหาก ซึ่งมีรายละเอียดอยู่ในเอกสารประกอบ เอกสารรายงาน 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

วิธีนี้จะสร้างรายงานผลการทดสอบในรูปแบบที่ดูดีและให้ข้อมูลครบถ้วน ดังนี้:

รายงาน

รายงานการทดสอบในรูปแบบ HTML

รายงานการทดสอบในรูปแบบ HTML

รายงานการทดสอบแสดงผลสถานการณ์แต่ละรายการ

ชุดเครื่องมือที่ใช้งานได้นั้นจะมีประโยชน์ก็ต่อเมื่อมันยังคงอ่านง่ายแม้ว่า API จะมีการพัฒนาไปเรื่อยๆ ซึ่งนี่คือจุดที่ระเบียบวินัยในการจัดการไฟล์ฟีเจอร์จะให้ผลตอบแทนที่ดี

แนวทางปฏิบัติที่ดีที่สุดสำหรับการเขียนไฟล์ฟีเจอร์ Behave

ชุด Behave จะด้อยประสิทธิภาพลงอย่างรวดเร็วเมื่อสถานการณ์จำลองอธิบายถึงการคลิกและข้อมูลที่ส่งผ่านแทนที่จะเป็นพฤติกรรม แนวทางปฏิบัติด้านล่างนี้จะช่วยให้ไฟล์ฟีเจอร์อ่านง่ายสำหรับผู้มีส่วนได้ส่วนเสียทางธุรกิจ ในขณะเดียวกันก็รักษา...ping Python เลเยอร์นี้ช่วยให้วิศวกรสามารถดูแลรักษาได้ง่าย

  1. อธิบายพฤติกรรม ไม่ใช่การนำไปใช้งาน เขียนว่า “เมื่อลูกค้ามีเงินคงเหลือเพียงพอ” ไม่ใช่ “เมื่อยอดเงินคงเหลือเท่ากับ 500” ไฟล์ฟีเจอร์ระบุว่าระบบทำอะไร ส่วนไฟล์สเต็ประบุวิธีการตรวจสอบ
  2. จำกัดพฤติกรรมไว้เพียงหนึ่งอย่างต่อสถานการณ์ สถานการณ์ที่ระบุรหัสสถานะ เนื้อหาการตอบกลับ และแถวในฐานข้อมูลนั้น แท้จริงแล้วคือสถานการณ์ย่อยสามสถานการณ์ การแยกสถานการณ์เหล่านี้ทำให้ความล้มเหลวสามารถระบุสาเหตุได้อย่างตรงจุด
  3. ย้ายการตั้งค่าที่ใช้ร่วมกันไปไว้ในพื้นหลัง ตัวอย่างข้างต้นใช้ Background: Given I set sample REST API url เพื่อให้ทุกสถานการณ์สืบทอดพื้นฐานนั้น URL โดยไม่พูดซ้ำ
  4. ใช้การกำหนดพารามิเตอร์แทนการทำซ้ำ ตัวยึดตำแหน่ง เช่น "{request_name}" ให้ฟังก์ชันขั้นตอนเดียวทำหน้าที่ตรวจสอบความถูกต้องของข้อมูล (GET, PUT และ DELETE) ซึ่งเป็นเหตุผลว่าทำไมตัวอย่างนี้จึงต้องการคำจำกัดความของขั้นตอนน้อยกว่าสถานการณ์จำลองมาก
  5. ใช้โครงร่างสถานการณ์จำลองสำหรับข้อมูลที่มีความแปรผัน เมื่อต้องพิสูจน์พฤติกรรมเดียวกันสำหรับอินพุตหลายตัว Examples: ตารางมีความชัดเจนกว่าการคัดลอกสถานการณ์จำลอง
  6. หลีกเลี่ยงการพึ่งพาซึ่งกันและกันระหว่างสถานการณ์ต่างๆ Behave ไม่รับประกันว่าสถานการณ์ POST จะทำงานก่อนสถานการณ์ GET ในทุกการตั้งค่า สถานการณ์แต่ละอย่างควรสร้างสถานะที่จำเป็นของตนเอง
  7. แทนที่ตัวแปรส่วนกลางระดับโมดูลด้วยตัวแปรบริบท ตัวอย่างนี้จัดเก็บเอนด์พอยต์และคำตอบไว้ในพจนานุกรมของโมดูลเพื่อความกระชับ ในชุดทดสอบจริง ควรจัดเก็บไว้ใน Behave context เพื่อให้สถานะของวัตถุถูกรีเซ็ตอย่างราบรื่นระหว่างสถานการณ์ต่างๆ
  8. สถานการณ์การติดแท็กสำหรับการทดลองใช้งานแบบเลือกเฉพาะ แท็กต่างๆ เช่น @smoke or @regression อนุญาต behave --tags=@smokeซึ่งช่วยให้การตอบรับจากกระบวนการทำงานรวดเร็วขึ้น

การนำนิสัยเหล่านี้ไปใช้ตั้งแต่ไฟล์ฟีเจอร์แรก จะทำให้ชุดเครื่องมือ BDD มีคุณค่ามากกว่าแค่ตัวอย่าง CRUD เริ่มต้น ทีมที่ต่อยอดแนวทางนี้มักจะนำไปใช้ร่วมกับวิธีการอื่นๆ ด้วย Cucumber สำหรับโปรเจ็กต์ JVM หรือ Postman สำหรับการตรวจสอบ API ในเชิงสำรวจ

คำถามที่พบบ่อย

ทั้งสองโปรแกรมอ่านไฟล์ฟีเจอร์ Gherkin Cucumber เชื่อมโยงขั้นตอนต่างๆ เข้าด้วยกัน Javaรูบี้ หรือ Javaสคริปต์ ในขณะที่ พฤติกรรม จะผูกมัดพวกมันเข้าด้วยกัน Pythonเลือกตัวเลือกที่ตรงกับสแต็กแอปพลิเคชันของคุณ เพื่อให้คำจำกัดความขั้นตอนนำยูทิลิตี้การทดสอบที่มีอยู่มาใช้ซ้ำ

ใช่แล้ว ฟังก์ชัน Behave จะส่งคืนรหัสออกที่ไม่ใช่ศูนย์เมื่อสถานการณ์ใดๆ ล้มเหลว ดังนั้น JenkinsGitLab CI หรือ GitHub Actions อาจทำให้การสร้างล้มเหลวโดยอัตโนมัติ เผยแพร่โฟลเดอร์ผลลัพธ์ของ Allure เป็นอาร์ติแฟกต์การสร้างเพื่อใช้ในการรายงาน

ใช่. AI ผู้ช่วยจะร่างสถานการณ์ Given-When-Then จากเรื่องราวของผู้ใช้หรือข้อกำหนด OpenAPI Revตรวจสอบผลลัพธ์สำหรับกรณีเชิงลบที่ขาดหายไปและกฎทางธุรกิจ เนื่องจากสถานการณ์ที่สร้างขึ้นมักครอบคลุมเฉพาะกรณีที่ราบรื่นเท่านั้น

เครื่องมือ AI ตรวจจับสถานการณ์ที่ซ้ำกันหรือเกือบซ้ำกัน แนะนำขั้นตอนที่สามารถนำกลับมาใช้ใหม่ได้ และจัดกลุ่มความล้มเหลวที่ไม่แน่นอนตามสาเหตุที่เป็นไปได้ ซึ่งจะช่วยลดความพยายามในการตรวจสอบด้วยตนเองเมื่อไฟล์ฟีเจอร์เพิ่มจำนวนขึ้นในหลายทีม

ดึงโทเค็นเพียงครั้งเดียวใน hook before_all ของ environment.py เก็บไว้ในอ็อบเจ็กต์ context และแนบเป็นส่วนหัว Authorization ในแต่ละขั้นตอนการร้องขอ เก็บข้อมูลรับรองไว้ในตัวแปรสภาพแวดล้อม ไม่ควรเก็บไว้ในไฟล์ฟีเจอร์

สรุปโพสต์นี้ด้วย: