Co je testování BDD? Rámcový příklad

Co je testování BDD (Behavior Driven Development)?

BDD (Behavior-driven development) Testování je technika agilního vývoje softwaru a je jako rozšíření TDD, tj. Test Driven Development. V BDD jsou testovací případy napsány v přirozeném jazyce, který mohou číst i neprogramátoři.

Jak funguje testování BDD?

Zvažte, že jste pověřeni vytvořením modulu Převod prostředků v aplikaci Net Banking.

Existuje několik způsobů, jak to otestovat

  1. Převod prostředků by měl proběhnout, pokud je na zdrojovém účtu dostatečný zůstatek
  2. Převod prostředků by měl proběhnout, pokud jsou podrobnosti o klimatizaci správné
  3. Převod prostředků by měl proběhnout, pokud je heslo transakce / kód rsa / bezpečnostní ověření pro transakci zadané uživatelem správné
  4. Převod prostředků by měl proběhnout, i když je státní svátek
  5. Převod prostředků by měl proběhnout k budoucímu datu stanovenému majitelem účtu

Jedno Scénář testu stávají se propracovanějšími a složitějšími, protože zvažujeme další funkce, jako je převod částky X za interval Y dní/měsíců, zastavení plánovaného převodu, když celková částka dosáhne Z atd.

Obecnou tendencí vývojářů je vyvíjet funkce a psát testovací kód později. Jak je patrné z výše uvedeného případu, Testovací případ vývoj pro tento případ je složitý a vývojář bude odkládat Testování do vydání, kdy provede rychlé, ale neúčinné testování.

K překonání tohoto problému (Behavior Driven Development) byl vytvořen BDD. Pro vývojáře to usnadňuje celý proces testování

V BDD, cokoli napíšete, musí jít do Daný-když-pak kroky. Podívejme se na stejný příklad výše v BDD

Given that a fund transfer module in net banking application has been developed
And I am accessing it with proper authentication
WhenI 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

Není snadné psát, číst a rozumět? Pokrývá všechny možné testovací případy pro modul převodu prostředků a lze jej snadno upravit tak, aby vyhovoval více. Také je to spíše jako psaní dokumentace pro modul převodu prostředků.

Co je testování REST API?

Vzhledem k tomu, že se REST stal v dnešní době poměrně populárním stylem pro vytváření API, stalo se stejně důležité automatizovat testovací případy REST API spolu s testovacími případy uživatelského rozhraní. Takže v podstatě tyto REST API testování zahrnuje testování akcí CRUD (Create-Read-Update-Delete) metodami POST, GET, PUT a DELETE.

Co je Behave?

Behave je jedním z populárních Python Testovací rámce BDD.

Podívejme se, jak funguje Behave:

Soubory funkcí jsou napsány vaším obchodním analytikem / sponzorem / kýmkoli, kdo v nich obsahuje scénáře vašeho chování. Má formát přirozeného jazyka popisující rys nebo část prvku s reprezentativními příklady očekávaných výsledků

Tyto kroky scénáře jsou mapovány s implementacemi kroků zapsanými v Python.

A volitelně existují některé ovládací prvky prostředí (kód pro spuštění před a po krocích, scénáře, funkce nebo celé střelecké utkání).

Začněme s nastavením našeho testovacího rámce pro automatizaci pomocí Behave:

Nastavení testovacího rámce BDD Chovej se na Windows

Instalace:

Nastavení projektu:

  • Vytvořte nový projekt
  • Vytvořte následující adresářovou strukturu:

Nastavení projektu

Soubory funkcí:

Pojďme tedy vytvořit soubor funkcí Sample_REST_API_Testing.feature mající funkci Provádění operací CRUD na službě „postů“.

V našem příkladu jsem použil http://jsonplaceholder.typicode.com/ příspěvky ukázka REST Service.

Příklad scénáře POST

Scenario: POST post example ->Here we are considering creating new post item using 'posts' service
Given: I set post posts API endpoint ->This is prerequisite for the test which is setting URL of posts service
When: I set HEADER param request content type as "application/json."
And set request body
And send POST HTTP request ->This is actual test step of sending a post request
Then: Then I receive valid HTPP response code 201 
And Response body "POST" is non-empty-> This is verification of response body	

Podobně můžete napsat zbývající scénáře následovně:

Nastavení projektu

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." 

Kroky implementace

Nyní pro kroky funkce používané ve výše uvedených scénářích můžete zapsat implementace Python soubory v adresáři „steps“.

Behave framework identifikuje funkci Step dekorátory odpovídajícími predikátu souboru prvků. Například daný predikát v souboru Feature Scenario hledá funkci kroku s dekorátorem „daným“. K podobné shodě dochází pro Kdy a potom. Ale v případě 'Ale', 'A', funkce Step používá dekoratér stejný jako předchozí krok. Například, pokud 'And' přijde pro daný, odpovídající dekorátor funkce kroku je @dán.

Například, když lze krok pro POST implementovat následovně:

@when (u'I Set HEADER param request content type as "{header_conent_type}"')
Mapping of When, here notice “application/json” is been passed from feature file for "{header_conent_type}” . This is called as parameterization


def step_impl (context, header_conent_type):
This is step implementation method signature

request_headers['Content-Type'] = header_conent_type
Step implementation code, here you will be setting content type for request header

Podobně bude implementace dalších kroků v souboru step python vypadat takto:

Kroky implementace

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 = 'http://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_conent_type}"')
def step_impl(context, header_conent_type):
    request_headers['Content-Type'] = header_conent_type

#You may also include "And" or "But" as a step - these are renamed by behave to take the name of their preceding step, so:
@when(u'Set request Body')
def step_impl(context):
    request_bodies['POST']={"title": "foo","body": "bar","userId": "1"}

#You may also include "And" or "But" as a step - these are renamed by behave to take the name of their preceding step, so:
@when(u'Send POST HTTP request')
def step_impl(context):
    # sending get request and saving response as response object
    response = requests.post(url=api_endpoints['POST_URL'], json=request_bodies['POST'], headers=request_headers)
    #response = requests.post(url=api_endpoints['POST_URL'], headers=request_headers) #https://jsonplaceholder.typicode.com/posts
    # extracting response text
    response_texts['POST']=response.text
    print("post response :"+response.text)
    # extracting response status_code
    statuscode = response.status_code
    response_codes['POST'] = statuscode

@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'] is 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'])

#You may also include "And" or "But" as a step - these are renamed by behave to take the name of their preceding step, so:
@when(u'Send GET HTTP request')
def step_impl(context):
    # sending get request and saving response as response object
    response = requests.get(url=api_endpoints['GET_URL'], headers=request_headers) #https://jsonplaceholder.typicode.com/posts
    # extracting response text
    response_texts['GET']=response.text
    # extracting response status_code
    statuscode = response.status_code
    response_codes['GET'] = statuscode

@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] is 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):
    # sending get request and saving response as response object  # response = requests.post(url=api_endpoints['POST_URL'], headers=request_headers) #https://jsonplaceholder.typicode.com/posts
    response = requests.put(url=api_endpoints['PUT_URL'], json=request_bodies['PUT'], headers=request_headers)
    # extracting response text
    response_texts['PUT'] = response.text
    print("update response :" + response.text)
    # extracting response status_code
    statuscode = response.status_code
    response_codes['PUT'] = statuscode
#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):
    # sending get request and saving response as response object
    response = requests.delete(url=api_endpoints['DELETE_URL'])
    # response = requests.post(url=api_endpoints['POST_URL'], headers=request_headers) #https://jsonplaceholder.typicode.com/posts
    # extracting response text
    response_texts['DELETE'] = response.text
    print("DELETE response :" + response.text)
    # extracting response status_code
    statuscode = response.status_code
    response_codes['DELETE'] = statuscode
#END DELETE

Provádění testů

Nyní jsme s vývojem testovacích skriptů hotovi, takže spusťte naše testy:

Spuštěním následujícího příkazu na příkazovém řádku spusťte náš soubor funkcí

C: \Programy\Python\Python37>chovat se -f pěkně C:\ \features\feature_files_folder\Sample_REST_API_Testing.feature

Tím se zobrazí výsledky provedení testu takto:

Provádění testů

Zobrazení zprávy na konzole

Podívejme se zde ještě na jednu super věc.

Protože uživatelé vždy preferují vidět výsledky testů v čitelnějším a prezentovatelnějším formátu, mějme s pomocí Allure zprávy ve formátu HTML.

zprávy

Nejprve musíte nainstalovat Allure Behave formatter [https://docs.qameta.io/allure-report/]:

A nyní proveďte následující příkaz:

Pro zprávy

>chovat -f json -o Sample_REST_API_Testing.feature

> lákat sloužit

Tím se vygeneruje zpráva o výsledcích testu v prezentovatelném a informativním formátu, jako je tento:

zprávy

Testovací zpráva ve formátu HTML

Testovací zpráva ve formátu HTML

Zpráva o testu zobrazující výsledek jednotlivých scénářů

Shrnutí

  • BDD je vývoj řízený chováním. Je to jedna z technik agilního vývoje softwaru.
  • REST se v dnešní době stal docela populárním stylem pro vytváření API, stejně důležité je automatizovat testovací případy REST API spolu s testovacími případy uživatelského rozhraní.
  • BDD má formát přirozeného jazyka popisující rys nebo část prvku s reprezentativními příklady očekávaných výsledků
  • Behave framework identifikuje funkci Step dekorátory odpovídajícími predikátu souboru prvků
  • Příklady rámců testování BDD: 1) Cucumber 2) SpecFlow 3) Quantum 4) JBehave 5) Codeception