Τι είναι το BDD Testing; Παράδειγμα πλαισίου

Τι είναι το BDD (Behavior Driven Development) Testing;

Δοκιμή BDD (Behavior-driven development). είναι μια τεχνική ευέλικτης ανάπτυξης λογισμικού και αποτελεί επέκταση του TDD, δηλαδή, Test Driven Development. Στο BDD, οι περιπτώσεις δοκιμών είναι γραμμένες σε μια φυσική γλώσσα που μπορούν να διαβάσουν ακόμη και οι μη προγραμματιστές.

Πώς λειτουργεί το BDD Testing;

Σκεφτείτε ότι σας έχει ανατεθεί να δημιουργήσετε τη μονάδα Μεταφοράς Χρημάτων σε μια εφαρμογή Net Banking.

Υπάρχουν πολλοί τρόποι για να το δοκιμάσετε

  1. Η μεταφορά χρημάτων θα πρέπει να πραγματοποιείται εάν υπάρχει αρκετό υπόλοιπο στον λογαριασμό πηγής
  2. Η μεταφορά χρημάτων θα πρέπει να πραγματοποιείται εάν ο προορισμός a/c details είναι σωστά
  3. Η μεταφορά χρημάτων πρέπει να πραγματοποιείται εάν ο κωδικός πρόσβασης συναλλαγής / ο κωδικός rsa / ο έλεγχος ταυτότητας ασφαλείας για τη συναλλαγή που έχει εισαχθεί από τον χρήστη είναι σωστός
  4. Η μεταφορά χρημάτων θα πρέπει να πραγματοποιείται ακόμη και αν είναι τραπεζική αργία
  5. Η μεταφορά κεφαλαίων θα πρέπει να πραγματοποιείται σε μελλοντική ημερομηνία όπως ορίζεται από τον κάτοχο του λογαριασμού

Η Σενάριο δοκιμής γίνονται πιο περίτεχνα και συνplex καθώς λαμβάνουμε υπόψη πρόσθετες λειτουργίες όπως το ποσό μεταφοράς X για ένα διάστημα Y ημέρες/μήνες, διακοπή της μεταφοράς χρονοδιαγράμματος όταν το συνολικό ποσό φτάσει το Z και ούτω καθεξής

Η γενική τάση των προγραμματιστών είναι να αναπτύσσουν δυνατότητες και να γράφουν κώδικα δοκιμής later. Όπως φαίνεται στην παραπάνω περίπτωση, Δοκιμαστική θήκη ανάπτυξη για αυτή την περίπτωση είναι complex και ο προγραμματιστής θα αναβάλει Δοκιμές μέχρι την απελευθέρωση, οπότε θα κάνει γρήγορο αλλά αναποτελεσματικό τεστ.

Για να ξεπεραστεί αυτό το ζήτημα (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
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

Δεν είναι εύκολο να γράψεις και να διαβάσεις και να καταλάβεις; Καλύπτει όλες τις πιθανές δοκιμαστικές περιπτώσεις για τη μονάδα μεταφοράς κεφαλαίων και μπορεί εύκολα να τροποποιηθεί για να φιλοξενήσει περισσότερες. Επίσης, μοιάζει περισσότερο με τη σύνταξη τεκμηρίωσης για τη μονάδα μεταφοράς κεφαλαίων.

Τι είναι το REST API Testing;

Καθώς το REST έχει γίνει ένα αρκετά δημοφιλές στυλ για τη δημιουργία API στις μέρες μας, έχει γίνει εξίσου σημαντικό να αυτοματοποιούνται περιπτώσεις δοκιμών REST API μαζί με περιπτώσεις δοκιμών διεπαφής χρήστη. Βασικά λοιπόν, αυτά ΑΝΑΠΑΥΘΟΥΝ Δοκιμή API περιλαμβάνει τη δοκιμή ενεργειών CRUD (Δημιουργία-Ανάγνωση-Ενημέρωση-Διαγραφή) με τις μεθόδους POST, GET, PUT και DELETE αντίστοιχα.

Τι είναι το Behave;

Το Behave είναι ένα από τα δημοφιλή πλαίσια δοκιμής Python BDD.

Ας δούμε πώς λειτουργεί το Behave:

Τα αρχεία δυνατοτήτων γράφονται από τον Business Analyst / Sponsor / όποιον έχει τα σενάρια συμπεριφοράς σας σε αυτά. Έχει μια μορφή φυσικής γλώσσας που περιγράφει ένα χαρακτηριστικό ή μέρος ενός χαρακτηριστικού με αντιπροσωπευτικά παραδείγματα αναμενόμενων αποτελεσμάτων

Αυτά τα βήματα του σεναρίου αντιστοιχίζονται με γραμμένες υλοποιήσεις βημάτων Python.

Και προαιρετικά, υπάρχουν ορισμένοι περιβαλλοντικοί έλεγχοι (κωδικός για εκτέλεση πριν και μετά τα βήματα, σενάρια, χαρακτηριστικά ή ολόκληρο τον αγώνα σκοποβολής).

Ας ξεκινήσουμε με τη ρύθμιση του πλαισίου δοκιμής αυτοματισμού με το Behave:

Ρύθμιση του πλαισίου δοκιμών BDD Behave on Windows

Εγκατάσταση:

  • Κατεβάστε και εγκαταστήστε την Python 3 από https://www.python.org/
  • Εκτελέστε το following εντολή στη γραμμή εντολών για εγκατάσταση συμπεριφέρονται
  • Συμπεριφορά εγκατάστασης pip
  • IDE: Έχω χρησιμοποιήσει το PyCharm Community Έκδοση https://www.jetbrains.com/pycharm/download

Ρύθμιση έργου:

  • Δημιουργήστε ένα νέο έργο
  • Δημιουργήστε το following Δομή καταλόγου:

Ρύθμιση έργου

Αρχεία δυνατοτήτων:

Ας δημιουργήσουμε λοιπόν το αρχείο χαρακτηριστικών μας Sample_REST_API_Testing.feature έχοντας χαρακτηριστικό ως Performing CRUD operaθέσεις για την υπηρεσία «αναρτήσεις».

Στο παράδειγμά μας, έχω χρησιμοποιήσει http://jsonplaceholder.typicode.com/ δείγμα της υπηρεσίας REST.

Παράδειγμα σεναρίου 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	

Ομοίως, μπορείτε να γράψετε τα υπόλοιπα σενάρια ως εξής:

Ρύθμιση έργου

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 στον κατάλογο «βήματα».

Το πλαίσιο συμπεριφοράς προσδιορίζει τη συνάρτηση Βήμα από διακοσμητές που ταιριάζουν με το κατηγόρημα του αρχείου χαρακτηριστικών. Για παράδειγμα, το κατηγόρημα δεδομένου στο σενάριο αρχείου χαρακτηριστικών αναζητά τη συνάρτηση βήματος με "δίνεται" ο διακοσμητής. Παρόμοια αντιστοίχιση συμβαίνει για Πότε και Τότε. Αλλά στην περίπτωση του «Αλλά», «Και», η λειτουργία Βήμα παίρνει τον διακοσμητή όπως και το προηγούμενο βήμα. Για παράδειγμα, εάν το 'And' εμφανίζεται για το Given, το αντίστοιχο βήμα διακοσμητής συνάρτησης είναι @given.

Για παράδειγμα, όταν το βήμα για POST μπορεί να εφαρμοστεί ως εξής:

@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

Ομοίως, η υλοποίηση άλλων βημάτων στο αρχείο step python θα μοιάζει με αυτό:

Βήματα Υλοποίηση

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

Εκτέλεση των δοκιμών

Τώρα, τελειώσαμε με το τμήμα ανάπτυξης σεναρίου δοκιμής, οπότε ας εκτελέσουμε τις δοκιμές μας:

Εκτελέστε το following εντολή στη γραμμή εντολών για την εκτέλεση του αρχείου χαρακτηριστικών μας

C: \Programs\Python\Python37>συμπεριφέρομαι -f όμορφος ΝΤΟ:\ \features\feature_files_folder\Sample_REST_API_Testing.feature

Αυτό θα εμφανίσει τα αποτελέσματα εκτέλεσης δοκιμής ως εξής:

Εκτέλεση των δοκιμών

Εμφάνιση αναφοράς στην κονσόλα

Ας δούμε ένα ακόμα ωραίο πράγμα εδώ.

Καθώς οι χρήστες προτιμούν πάντα να βλέπουν τα αποτελέσματα των δοκιμών σε περισσότερα readable και εμφανίσιμη μορφή, ας έχουμε αναφορές σε μορφή HTML με τη βοήθεια του Allure.

Εκθέσεις

Πρώτα, πρέπει να εγκαταστήσετε το μορφοποιητή Allure Behave [https://docs.qameta.io/allure-report/]:

Και τώρα εκτελέστε το following εντολή:

Για αναφορές

>συμπεριφέρομαι -f json -o Sample_REST_API_Testing.feature

> σέρβις γοητείας

Αυτό θα δημιουργήσει την αναφορά των αποτελεσμάτων των δοκιμών σας σε παρουσιάσιμη και ενημερωτική μορφή ως εξής:

Εκθέσεις

Έκθεση δοκιμής σε μορφή HTML

Έκθεση δοκιμής σε μορφή HTML

Έκθεση δοκιμής που εμφανίζει μεμονωμένο αποτέλεσμα σεναρίου

Χαρακτηριστικά

  • Το BDD είναι ανάπτυξη που βασίζεται στη συμπεριφορά. Είναι μια από τις τεχνικές της ευέλικτης ανάπτυξης λογισμικού.
  • Το REST έχει γίνει ένα αρκετά δημοφιλές στυλ για τη δημιουργία API στις μέρες μας, έχει γίνει εξίσου σημαντικό να αυτοματοποιούνται περιπτώσεις δοκιμών REST API μαζί με περιπτώσεις δοκιμών διεπαφής χρήστη.
  • Το BDD έχει μια μορφή φυσικής γλώσσας που περιγράφει ένα χαρακτηριστικό ή μέρος ενός χαρακτηριστικού με αντιπροσωπευτικά παραδείγματα αναμενόμενων αποτελεσμάτων
  • Το πλαίσιο συμπεριφοράς προσδιορίζει τη συνάρτηση Βήμα από διακοσμητές που ταιριάζουν με το κατηγόρημα του αρχείου χαρακτηριστικών
  • Παραδείγματα πλαισίων δοκιμής BDD: 1) Cucumber 2) SpecFlow 3) Quantum 4) JBehave 5) Codeception