Ce este testarea BDD? Exemplu cadru

Ce este testarea BDD (Behavior Driven Development)?

Testare BDD (Behavior-driven development). este o tehnică de dezvoltare software agilă și este ca o extensie a TDD, adică, Test Driven Development. În BDD, cazurile de testare sunt scrise într-un limbaj natural pe care chiar și non-programatorii îl pot citi.

Cum funcționează testarea BDD?

Considerați că sunteți desemnat să creați un modul de transfer de fonduri într-o aplicație Net Banking.

Există mai multe moduri de a-l testa

  1. Transferul de fond ar trebui să aibă loc dacă există suficient sold în contul sursă
  2. Transferul de fond ar trebui să aibă loc dacă detaliile a/c de destinație sunt corecte
  3. Transferul de fond ar trebui să aibă loc dacă parola tranzacției / codul rsa / autentificarea de securitate pentru tranzacția introdusă de utilizator este corectă
  4. Transferul de fond ar trebui să aibă loc chiar dacă este o sărbătoare bancară
  5. Transferul de fond ar trebui să aibă loc la o dată viitoare stabilită de titularul contului

Scenariu de testare devin mai elaborate și mai complexe pe măsură ce luăm în considerare caracteristici suplimentare, cum ar fi suma de transfer X pentru un interval Y zile/luni, oprirea programului de transfer când suma totală ajunge la Z și așa mai departe

Tendința generală a dezvoltatorilor este de a dezvolta funcții și de a scrie codul de testare mai târziu. După cum este evident în cazul de mai sus, Caz de testare dezvoltarea pentru acest caz este complexă și dezvoltatorul va amâna Testarea până la eliberare, moment în care va face teste rapide, dar ineficiente.

Pentru a depăși această problemă (Behavior Driven Development) a fost conceput BDD. Face întregul proces de testare ușor pentru un dezvoltator

În BDD, orice ai scrie trebuie să intre Dat-Când-Atunci trepte. Să luăm în considerare același exemplu de mai sus în 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

Nu este ușor să scrii, să citești și să înțelegi? Acesta acoperă toate cazurile de testare posibile pentru modulul de transfer de fonduri și poate fi modificat cu ușurință pentru a găzdui mai multe. De asemenea, este mai mult ca scrierea documentației pentru modulul de transfer de fonduri.

Ce este testarea API REST?

Întrucât REST a devenit un stil destul de popular pentru construirea de API-uri în zilele noastre, a devenit la fel de importantă automatizarea cazurilor de testare a API-ului REST împreună cu cazurile de testare a UI. Deci, practic, acestea REST Testare API implică testarea acțiunilor CRUD (Create-Read-Update-Delete) cu metodele POST, GET, PUT și, respectiv, DELETE.

Ce este Behave?

Behave este una dintre cele populare Python Cadre de testare BDD.

Să vedem cum funcționează Behave:

Fișierele caracteristice sunt scrise de analistul dvs. de afaceri / sponsorul / oricine are scenariile dvs. de comportament în ele. Are un format în limbaj natural care descrie o caracteristică sau o parte a unei caracteristici cu exemple reprezentative ale rezultatelor așteptate

Acești pași ai scenariului sunt mapați cu implementări ale pașilor scrise Python.

Și, opțional, există unele controale de mediu (cod de rulat înainte și după pași, scenarii, caracteristici sau întregul meci de tir).

Să începem cu configurarea cadrului nostru de testare de automatizare cu Behave:

Configurarea cadrului de testare BDD Behave on Windows

Instalare:

Configurare proiect:

  • Creați un nou proiect
  • Creați următoarea structură de director:

Configurare proiect

Fișiere de caracteristici:

Deci, să construim fișierul nostru de caracteristici Sample_REST_API_Testing.feature având funcția de Efectuare a operațiunilor CRUD pe serviciul „postări”.

În exemplul nostru, am folosit http://jsonplaceholder.typicode.com/ postează un exemplu de serviciu REST.

Exemplu de scenariu 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	

În mod similar, puteți scrie scenariile rămase după cum urmează:

Configurare proiect

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

Etape de implementare

Acum, pentru Pașii caracteristici utilizați în scenariile de mai sus, puteți scrie implementări în Python fișierele din directorul „pași”.

Framework Behave identifică funcția Step de către decoratori care se potrivesc cu predicatul fișierului de caracteristici. De exemplu, predicatul dat în fișierul de caracteristici Scenariul caută funcția pas având decoratorul „dat”. Potriviri similare se întâmplă pentru Când și Atunci. Dar în cazul „Dar”, „Și”, funcția Pas ia decoratorul la fel ca pasul precedent. De exemplu, dacă „Și” vine pentru Given, decoratorul funcției de pas care se potrivește este @given.

De exemplu, când pasul pentru POST poate fi implementat după cum urmează:

@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

În mod similar, implementarea altor pași în fișierul step python va arăta astfel:

Etape de implementare

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

Derularea Testelor

Acum, am terminat cu partea noastră de dezvoltare a scriptului de testare, așa că haideți să ne rulăm testele:

Executați următoarea comandă la promptul de comandă pentru a rula fișierul nostru de caracteristici

C: \Programe\Python\Python37>se comportă -f frumos C:\ \features\feature_files_folder\Sample_REST_API_Testing.feature

Aceasta va afișa rezultatele execuției testului după cum urmează:

Derularea Testelor

Afișarea raportului pe consolă

Să mai vedem un lucru tare aici.

Deoarece utilizatorii preferă întotdeauna să vadă rezultatele testelor într-un format mai lizibil și mai prezentabil, să avem rapoarte în format HTML cu ajutorul Allure.

Rapoarte

Mai întâi, trebuie să instalați formatatorul Allure Behave [https://docs.qameta.io/allure-report/]:

Și acum executați următoarea comandă:

Pentru rapoarte

>se comportă -f json -o Sample_REST_API_Testing.feature

> alura servi

Aceasta va genera raportul dvs. de rezultate ale testului într-un format prezentabil și informativ, astfel:

Rapoarte

Raport de testare în format HTML

Raport de testare în format HTML

Raport de testare care afișează rezultatul scenariului individual

Rezumat

  • BDD este o dezvoltare bazată pe comportament. Este una dintre tehnicile dezvoltării agile de software.
  • REST a devenit un stil destul de popular pentru construirea de API-uri în zilele noastre, a devenit la fel de importantă automatizarea cazurilor de testare a API-ului REST împreună cu cazurile de testare a UI.
  • BDD are un format în limbaj natural care descrie o caracteristică sau o parte a unei caracteristici cu exemple reprezentative ale rezultatelor așteptate
  • Framework Behave identifică funcția Step de către decoratori care se potrivesc cu predicatul fișierului de caracteristici
  • Exemple de cadre de testare BDD: 1) Cucumber 2) SpecFlow 3) Quantum 4) JBehave 5) Codeception