Разделы портала

Онлайн-тренинги

.
Создание API тестов на Python через Tavern
28.10.2019 00:00

Автор: Баз Дейкстра (Bas Dijkstra)
Оригинал статьи
Перевод: Ольга Алифанова

Статьи об инструментах, которые я писал ранее, в основном концентрировались на Java или C#. Однако недавно меня попросили о тренинге по тест-автоматизации для группы инженеров по Data Science, с явным требованием использовать инструменты на основе Python для примеров и упражнений.

С тех пор я постепенно расширял свои познания, чтобы включить в них экосистему Python, и я также включил ряд основанных на Python курсов по автоматизации в свои тренинги. Пока что я впечатлен! Для Python существует множество мощных тест-инструментов, и в этой статье я бы хотел подробнее остановиться на одном из них – Tavern.

Tavern – это фреймворк тестирования API, работающий на основе pytest, одного из наиболее популярных Python-фреймворков для юнит-тестирования. Он предлагает целый ряд возможностей для создания и запуска API-тестов, а если что-то нельзя сделать через Tavern, то его можно легко расширить через возможности Python или pytest. Не могу поручиться за эту расширяемость, потому что пока что я пользовался исключительно встроенными в Tavern возможностями. У Tavern также хорошая документация, и это очень приятно.


Установить Tavern на свою машину проще всего через pip, Python-пакет установки и управления, используя следующую команду:

pip install -U tavern

Тесты в Tavern пишутся в YAML-файлы. Вы можете любить их или ненавидеть, однако это работает. Для начала давайте напишем тест, который получает данные локации для индекса США 90210 через Zippopotam.us API, и проверки, убеждающиеся, что код HTTP-ответа равен 200. Вот так это выглядит в Tavern:

test_name: Get location for US zip code 90210 and check response status code
 
stages:
- name: Check that HTTP status code equals 200
request:
url: http://api.zippopotam.us/us/90210
method: GET
response:
status_code: 200

Как я уже говорил, Tavern работает на основе pytest. Для запуска этого теста нужно вызвать pytest и сообщить, что тесты, нуждающиеся в прогоне, находятся в созданном нами YAML-файле:


Как можно видеть, тест пройден.

Вам также может понадобиться проверка значений для отдельных заголовков ответа. Давайте убедимся, что content-type ответа равен "application/json", и сообщает пользователю API, что ответ нужно интерпретировать как JSON:

test_name: Get location for US zip code 90210 and check response content type
 
stages:
- name: Check that content type equals application/json
request:
url: http://api.zippopotam.us/us/90210
method: GET
response:
headers:
content-type: application/json

Конечно, можно также проверять и тело ответа. Вот пример, проверяющий, что название локации, ассоциирующейся с вышеупомянутым индексом США 90210 – это "Beverly Hills":

test_name: Get location for US zip code 90210 and check response body content
 
stages:
- name: Check that place name equals Beverly Hills
request:
url: http://api.zippopotam.us/us/90210
method: GET
response:
body:
places:
- place name: Beverly Hills

Так как API – это в первую очередь данные, то вам, возможно, понадобится повторить тест не один раз, используя разные значения для параметров запроса и ожидаемых результатов (то есть проводить тестирование на основе данных). Tavern поддерживает такой подход через маркер pytest – parametrize.

test_name: Check place name for multiple combinations of country code and zip code
 
marks:
- parametrize:
key:
- country_code
- zip_code
- place_name
vals:
- [us, 12345, Schenectady]
- [ca, B2A, North Sydney South Central]
- [nl, 3825, Vathorst]
 
stages:
- name: Verify place name in response body
request:
url: http://api.zippopotam.us/{country_code}/{zip_code}
method: GET
response:
body:
places:
- place name: "{place_name}"

Несмотря на то, что мы написали один тест, состоящий из одного этапа, использование маркера parametrize и трех вариантов данных позволяет pytest успешно прогнать три теста (это похоже на работу @DataProvider в TestNG для Java):


Пока что мы выполняли только GET-операции для получения данных от поставщика API, и поэтому не описывали содержание тела запроса. Если вы, как потребитель API, хотите отправить поставщику какие-то данные – например, через операции POST или PUT – то через Tavern это можно реализовать так:

test_name: Check response status code for a very simple addition API
 
stages:
- name: Verify that status code equals 200 when two integers are specified
request:
url: http://localhost:5000/add
json:
first_number: 5
second_number: 6
method: POST
response:
status_code: 200

Этот тест отправит JSON-документ через POST-запрос

{'first_number': 5, 'second_number': 6}

к поставщику API, работающему по адресу localhost: порт 5000. Пожалуйста, имейте в виду, что по очевидным причинам этот тест упадет, если вы попробуете его запустить – если вы, конечно, не создадите API или заглушку, которая позволит этому тесту пройти успешно (отличное упражнение, кстати говоря).

Это было краткое введение в Tavern. Мне очень нравится этот инструмент, в первую очередь своей прямотой. Меня интересует, не приведет ли работа с YAML к проблемам поддерживаемости и читабельности при работе с большими наборами тестов и большими телами запросов или ответов. Я буду продолжать работать с Tavern в своих тренингах, поэтому ожидайте следующей статьи!

Все примеры можно найти на этой странице в GitHub.

Обсудить в форуме