¿Qué son las pruebas BDD? Ejemplo de marco
¿Qué son las pruebas BDD (desarrollo impulsado por el comportamiento)?
Pruebas BDD (desarrollo impulsado por el comportamiento) es una técnica de desarrollo ágil de software y es una extensión de TDD, es decir, Test Driven Development. En BDD, los casos de prueba se escriben en un lenguaje natural que incluso los no programadores pueden leer.
¿Cómo funcionan las pruebas BDD?
Considere que está asignado a crear un módulo de transferencia de fondos en una aplicación de Net Banking.
Hay varias formas de probarlo.
- La transferencia de fondos debe realizarse si hay suficiente saldo en la cuenta de origen
- La transferencia de fondos debe realizarse si los detalles de la cuenta de destino son correctos
- La transferencia de fondos debe realizarse si la contraseña de la transacción/código rsa/autenticación de seguridad para la transacción ingresada por el usuario es correcta
- La transferencia de fondos debe realizarse incluso si es un día festivo
- La transferencia de fondos debe realizarse en una fecha futura establecida por el titular de la cuenta.
El sistema Escenario de prueba se vuelven más elaborados y complejos a medida que consideramos características adicionales como la transferencia de un monto X por un intervalo de Y días/meses, detener la transferencia programada cuando el monto total llega a Z, etc.
La tendencia general de los desarrolladores es desarrollar funciones y escribir el código de prueba más tarde. Como se evidencia en el caso anterior, Caso de prueba El desarrollo de este caso es complejo y el desarrollador lo pospondrá. Pruebas hasta su lanzamiento, momento en el que realizará pruebas rápidas pero ineficaces.
Para superar este problema (Behavior Driven Development) se concibió BDD. Facilita todo el proceso de prueba para un desarrollador.
En BDD, todo lo que escriba debe ir a Dado-cuando-entonces pasos. Consideremos el mismo ejemplo anterior en 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
¿No es fácil escribir, leer y comprender? Cubre todos los casos de prueba posibles para el módulo de transferencia de fondos y se puede modificar fácilmente para dar cabida a más. Además, es más como escribir documentación para el módulo de transferencia de fondos.
¿Qué son las pruebas de API REST?
Dado que REST se ha convertido en un estilo bastante popular para crear API hoy en día, se ha vuelto igualmente importante automatizar los casos de prueba de API REST junto con los casos de prueba de UI. Básicamente, estos DESCANSO Pruebas de API Implica probar acciones CRUD (Crear-Leer-Actualizar-Eliminar) con los métodos POST, GET, PUT y DELETE respectivamente.
¿Qué es comportarse?
Comportarse es uno de los populares. Python Marcos de prueba BDD.
Veamos cómo funciona Behave:
Los archivos de características son escritos por su analista de negocios/patrocinador/cualquier persona que incluya sus escenarios de comportamiento. Tiene un formato de lenguaje natural que describe una característica o parte de una característica con ejemplos representativos de los resultados esperados.
Estos pasos del escenario están mapeados con implementaciones de pasos escritas en Python.
Y, opcionalmente, hay algunos controles ambientales (código para ejecutar antes y después de los pasos, escenarios, características o todo el tiroteo).
Comencemos con la configuración de nuestro marco de prueba de automatización con Behave:
Configuración del marco de pruebas BDD Comportarse en Windows
Instalación:
- Descarga e instala Python 3 de https://www.python.org/
- Ejecute el siguiente comando en el símbolo del sistema para instalar el comportamiento
- comportamiento de instalación de pip
- IDE: He utilizado PyCharm Community Edition https://www.jetbrains.com/pycharm/download
Configuración del proyecto:
- Crear un nuevo proyecto
- Cree la siguiente estructura de directorio:
Archivos de características:
Entonces, creemos nuestro archivo de funciones. Característica_muestra_REST_API_Testing. que tiene una función como Realizar operaciones CRUD en el servicio 'publicaciones'.
En nuestro ejemplo, he usado http://jsonplaceholder.typicode.com/ publica un servicio REST de muestra.
Ejemplo de escenario 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
De manera similar, puedes escribir los Escenarios restantes de la siguiente manera:
Característica_muestra_REST_API_Testing.
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."
Implementación de pasos
Ahora, para los pasos de funciones utilizados en los escenarios anteriores, puede escribir implementaciones en Python archivos en el directorio “pasos”.
El marco de comportamiento identifica la función Paso mediante decoradores que coinciden con el predicado del archivo de características. Por ejemplo, el predicado dado en el escenario del archivo de características busca una función de paso que tenga un decorador "dado". Se produce una coincidencia similar para Cuando y Entonces. Pero en el caso de "Pero", "Y", la función de paso toma el mismo decorador que el paso anterior. Por ejemplo, si 'Y' viene por Dado, el decorador de función de paso coincidente es @dado.
Por ejemplo, cuando el paso para POST se puede implementar de la siguiente manera:
@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
De manera similar, la implementación de otros pasos en el archivo de pasos de Python se verá así:
ejemplo_paso_implementación.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
Ejecutando las pruebas
Ahora que hemos terminado con nuestra parte de desarrollo del script de prueba, ejecutemos nuestras pruebas:
Ejecute el siguiente comando en el símbolo del sistema para ejecutar nuestro archivo de funciones
C:\Programas\Python\Python37>comportarse -f bonita C:\\features\feature_files_folder\Característica_muestra_REST_API_Testing.
Esto mostrará los resultados de la ejecución de la prueba de la siguiente manera:
Visualización de informes en la consola.
Veamos una cosa interesante más aquí.
Como los usuarios siempre prefieren ver los resultados de las pruebas en un formato más legible y presentable, tengamos informes en formato HTML con la ayuda de Allure.
Informes
Primero, necesita instalar el formateador Allure Behave [https://docs.qameta.io/allure-report/]:
Y ahora ejecuta el siguiente comando:
Para informes
>comportarse -f json -o Característica_muestra_REST_API_Testing.
> servicio de encanto
Esto generará el informe de resultados de su prueba en un formato presentable e informativo como este:
Informe de prueba en formato HTML
Informe de prueba que muestra el resultado del escenario individual
Resumen
- BDD es desarrollo impulsado por el comportamiento. Es una de las técnicas de desarrollo ágil de software.
- REST se ha convertido en un estilo bastante popular para crear API hoy en día; se ha vuelto igualmente importante automatizar los casos de prueba de API REST junto con los casos de prueba de UI.
- BDD tiene un formato de lenguaje natural que describe una característica o parte de una característica con ejemplos representativos de los resultados esperados.
- El marco de comportamiento identifica la función Paso mediante decoradores que coinciden con el predicado del archivo de características
- Ejemplos de marcos de prueba de BDD: 1) Cucumber 2) SpecFlow 3) Quantum 4) JBehave 5) Codecepción