Hvad er BDD-testning? Rammeeksempel

Hvad er BDD-test (Behavior Driven Development)?

BDD (Adfรฆrdsdrevet udvikling) Test er en teknik til agil softwareudvikling og er i forlรฆngelse af TDD, dvs. Test Driven Development. I BDD er testcases skrevet i et naturligt sprog, som selv ikke-programmรธrer kan lรฆse.

Hvordan fungerer BDD-test?

Overvej, at du er blevet tildelt til at oprette pengeoverfรธrselsmodul i en Net Banking-applikation.

Der er flere mรฅder at teste det pรฅ

  1. Pengeoverfรธrsel bรธr finde sted, hvis der er nok saldo pรฅ kildekontoen
  2. Pengeoverfรธrsel bรธr finde sted, hvis destinations-a/c-oplysningerne er korrekte
  3. Pengeoverfรธrsel bรธr finde sted, hvis transaktionsadgangskode / rsa-kode / sikkerhedsgodkendelse for transaktionen indtastet af brugeren er korrekt
  4. Pengeoverfรธrsel bรธr finde sted, selvom det er en helligdag
  5. Pengeoverfรธrsel bรธr finde sted pรฅ en fremtidig dato som fastsat af kontohaveren

Testscenarie blive mere kompliceret og kompleks, da vi overvejer yderligere funktioner som overfรธrselsbelรธb X i et interval Y dage/mรฅneder , stop tidsplanoverfรธrsel, nรฅr det samlede belรธb nรฅr Z , og sรฅ videre

Den generelle tendens hos udviklere er at udvikle funktioner og skrive testkode senere. Som det fremgรฅr af ovenstรฅende tilfรฆlde, Test sag udvikling for denne sag er kompleks, og udvikleren vil udsรฆtte Test indtil frigivelse, hvorefter han vil lave hurtige, men ineffektive tests.

For at overvinde dette problem (Behavior Driven Development) blev BDD udtรฆnkt. Det gรธr hele testprocessen let for en udvikler

I BDD skal det, du skriver, gรฅ ind i Givet-Hvornรฅr-Sรฅ trin. Lad os overveje det samme eksempel ovenfor i 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

Er det ikke nemt at skrive og lรฆse og forstรฅ? Det dรฆkker alle mulige testcases for pengeoverfรธrselsmodulet og kan nemt รฆndres, sรฅ det kan rumme flere. Det er ogsรฅ mere som at skrive dokumentation til fondsoverfรธrselsmodulet.

Hvad er REST API-testning?

Da REST er blevet en ganske populรฆr stil til at bygge API'er i dag, er det blevet lige sรฅ vigtigt at automatisere REST API-testcases sammen med UI-testcases. Sรฅ dybest set HVILER disse API-test involverer test af CRUD (Create-Read-Update-Delete) handlinger med henholdsvis metoderne POST, GET, PUT og DELETE.

Hvad er Behave?

Behave er en af โ€‹โ€‹de populรฆre Python BDD-testrammer.

Lad os se, hvordan Behave fungerer:

Funktionsfiler er skrevet af din forretningsanalytiker / sponsor / hvem som helst med dine adfรฆrdsscenarier i det. Det har et naturligt sprogformat, der beskriver en funktion eller en del af en funktion med reprรฆsentative eksempler pรฅ forventede resultater

Disse scenarietrin er kortlagt med trinimplementeringer skrevet ind Python.

Og valgfrit er der nogle miljรธkontroller (kode til at kรธre fรธr og efter trin, scenarier, funktioner eller hele skydekampen).

Lad os komme i gang med opsรฆtningen af โ€‹โ€‹vores automatiseringstestramme med Behave:

Opsรฆtning af BDD Testing Framework Behave on Windows

Installation:

Projektopsรฆtning:

  • Opret et nyt projekt
  • Opret fรธlgende mappestruktur:

Projektopsรฆtning

Funktionsfiler:

Sรฅ lad os bygge vores feature-fil Sample_REST_API_Testing.feature har funktion som Udfรธrelse af CRUD-operationer pรฅ 'posts'-tjeneste.

I vores eksempel har jeg brugt http://jsonplaceholder.typicode.com/ poster eksempel REST Service.

Eksempel POST-scenarie

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	

Pรฅ samme mรฅde kan du skrive de resterende scenarier som fรธlger:

Projektopsรฆtning

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

Trin implementering

Nu, for funktionstrin, der bruges i ovenstรฅende scenarier, kan du skrive implementeringer i Python filer i mappen "trin".

Behave framework identificerer Step-funktionen ved at dekoratรธrer matcher med feature fil-prรฆdikatet. For eksempel sรธger et givet prรฆdikat i Feature-fil Scenario efter trinfunktion, der har dekorator "givet". Tilsvarende matching sker for Hvornรฅr og derefter. Men i tilfรฆlde af 'Men', 'Og', tager Trin-funktionen dekorator samme som det foregรฅende trin. For eksempel, hvis 'And' kommer for Given, er matchende trinfunktionsdekorator @given.

For eksempel, nรฅr trin til POST kan implementeres som fรธlger:

@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

Pรฅ samme mรฅde vil implementeringen af โ€‹โ€‹andre trin i step python-filen se sรฅdan ud:

Trin implementering

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

Afvikling af testene

Nu er vi fรฆrdige med vores testscript-udviklingsdel, sรฅ lad os kรธre vores test:

Udfรธr fรธlgende kommando pรฅ kommandoprompten for at kรธre vores funktionsfil

C: \Programmer\Python\Python37>opfรธre sig -f smuk C:\ \features\feature_files_mappe\Sample_REST_API_Testing.feature

Dette vil vise testudfรธrelsesresultater som fรธlger:

Afvikling af testene

Rapportvisning pรฅ konsollen

Lad os se endnu en fed ting her.

Da brugere altid foretrรฆkker at se testresultater i et mere lรฆsbart og prรฆsentabelt format, lad os have rapporter i HTML-format ved hjรฆlp af Allure.

Rapporter

Fรธrst skal du installere Allure Behave formatter [https://docs.qameta.io/allure-report/]:

Og udfรธr nu fรธlgende kommando:

Til rapporter

>opfรธre sig -f json -o Sample_REST_API_Testing.feature

> lokkende tjene

Dette vil generere din testresultatrapport i det prรฆsentable og informative format som dette:

Rapporter

Testrapport i HTML-format

Testrapport i HTML-format

Testrapport, der viser individuelle scenarieresultater

Resumรฉ

  • BDD er adfรฆrdsdrevet udvikling. Det er en af โ€‹โ€‹teknikkerne til agil softwareudvikling.
  • REST er blevet en ganske populรฆr stil til at bygge API'er i dag, det er blevet lige sรฅ vigtigt at automatisere REST API-testcases sammen med UI-testcases.
  • BDD har et naturligt sprogformat, der beskriver en funktion eller en del af en funktion med reprรฆsentative eksempler pรฅ forventede resultater
  • Behave framework identificerer Step-funktionen ved at dekoratรธrer matcher med feature fil-prรฆdikatet
  • Eksempler pรฅ BDD-testrammer: 1) Cucumber 2) SpecFlow 3) Quantum 4) JBehave 5) Codeundtagelse

Opsummer dette indlรฆg med: