Что такое тестирование BDD?
BDD (разработка на основе поведения) Тестирование — это метод гибкой разработки программного обеспечения, являющийся расширением TDD, т. Е. Разработка через тестирование. В BDD тестовые случаи написаны на естественном языке, который могут читать даже непрограммисты.
В этом уроке по BDD мы увидим BDD-тестирование REST API с Behave и Python.
- Как работает BDD Testing?
- Что такое REST API Testing?
- Что такое поведение?
- Настройка Behave Test Framework в Windows:
- Пример сценария POST:
- Шаги реализации
- Запуск тестов:
- Отчеты
Как работает BDD Testing?
Предположим, вы назначены для создания модуля «Перевод средств» в приложении Net Banking.
Есть несколько способов проверить это
- Перевод средств должен осуществляться, если на исходном счете достаточно средств.
- Перечисление средств должно быть выполнено, если информация о пункте назначения правильна
- Перевод средств должен выполняться, если пароль транзакции / код RSA / аутентификация безопасности для транзакции, введенной пользователем, верны
- Перевод средств должен осуществляться, даже если это банковский выходной
- Перевод средств должен состояться в будущем, как это установлено владельцем счета
Тестовый сценарий стал более сложным и сложным , как мы считаем , дополнительные функции , такие как суммы перевода X для интервала Y дней / месяцев, передачи по расписанию остановки , когда общая сумма достигает Z, и так далее
Общая тенденция разработчиков — разрабатывать функции и писать тестовый код позже. Как видно из приведенного выше случая, разработка Test Case для этого случая сложна, и разработчик отложит тестирование до выпуска, после чего он проведет быстрое, но неэффективное тестирование.
Чтобы преодолеть эту проблему (Behavior Driven Development) BDD был задуман. Это делает весь процесс тестирования простым для разработчика
В BDD все, что вы пишете, должно идти в шаги Given-When-Then . Давайте рассмотрим тот же пример выше в 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 вместе с тестовыми примерами пользовательского интерфейса. Таким образом, в основном, это тестирование REST API включает тестирование действий CRUD (Create-Read-Update-Delete) с методами POST, GET, PUT и DELETE соответственно.
Что такое поведение?
Behave — одна из популярных платформ Python BDD для тестирования.
Давайте посмотрим, как работает Behave:
Файлы компонентов пишутся вашим бизнес-аналитиком / спонсором / кем-либо, кто имеет ваши сценарии поведения. Он имеет формат на естественном языке, описывающий функцию или часть функции с характерными примерами ожидаемых результатов.
Эти шаги сценария отображаются с реализациями шагов, написанными на Python
И, опционально, есть некоторые элементы управления средой (код для запуска до и после шагов, сценарии, функции или весь матч по стрельбе).
Давайте начнем с настройки нашей инфраструктуры тестирования автоматизации с Behave:
Настройка Behave Test Framework в Windows:
Установка:
- Загрузите и установите Python 3 с https://www.python.org/
- Выполните следующую команду в командной строке, чтобы установить поведение
- pip install ведут себя
- IDE: я использовал PyCharm Community Edition https://www.jetbrains.com/pycharm/download
Настройка проекта:
- Создать новый проект
- Создайте следующую структуру каталогов:
Особые файлы:
Итак, давайте создадим наш функциональный файл Sample_REST_API_Testing.feature, имеющий функцию, выполняющую операции CRUD на службе «posts».
В нашем примере я использовал http://jsonplaceholder.typicode.com/ posts пример службы 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 в каталоге «steps».
Структура поведения идентифицирует функцию Step с помощью декораторов, соответствующих предикату файла функций. Например, данный предикат в Сценарии файла объектов выполняет поиск функции шага, имеющей декоратор «задано». Подобное совпадение происходит для Когда и Тогда. Но в случае «Но», «И» функция Step принимает декоратор так же, как и предыдущий шаг. Например, если для заданного дано «И», соответствующий декоратор пошаговой функции — @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
Аналогично, реализация других шагов в файле шага 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
Запуск тестов:
Теперь мы закончили с нашей частью разработки тестового скрипта, поэтому давайте запустим наши тесты:
Выполните следующую команду в командной строке, чтобы запустить наш файл функций
C: \ Programs \ Python \ Python37> ведут себя -f довольно C: \ <путь к вашему проекту> \ features \ feature_files_folder \ Sample_REST_API_Testing.feature
Это отобразит результаты выполнения теста следующим образом:
Отображение отчета на консоли
Давайте посмотрим еще одну классную вещь здесь.
Поскольку пользователи всегда предпочитают видеть результаты тестов в более удобочитаемом и презентабельном формате, давайте создадим отчеты в формате HTML с помощью Allure.
Отчеты
Во-первых, вам необходимо установить форматер Allure Behave [ https://docs.qameta.io/allure/ ]:
А теперь выполните следующую команду:
Для отчетов
> вести себя -f json -o <путь-к-папке-отчету> Sample_REST_API_Testing.feature
<путь к папке allure-bin >> allure serve <путь к папке отчета>
Это сгенерирует ваш отчет о результатах теста в презентабельном и информативном формате, например:
Протокол испытаний в формате HTML
Отчет о тестировании, отображающий индивидуальный результат сценария
Резюме:
- BDD — это развитие, основанное на поведении. Это один из методов гибкой разработки программного обеспечения.
- В настоящее время REST стал довольно популярным стилем для создания API, и в равной степени важно автоматизировать тестовые случаи REST API вместе с тестовыми примерами пользовательского интерфейса.
- BDD имеет формат на естественном языке, описывающий функцию или часть функции с типичными примерами ожидаемых результатов
- Behave Framework идентифицирует функцию Step с помощью декораторов, соответствующих предикату файла функций.