HTTP запросы
Описание запросов
При помощи механизма HTTP-запросов можно напрямую обращаться к веб-серверу минуя взаимодействия с браузером. Этот механизм в первую очередь предназначен для дополнения браузерного тестирования, а не для создания самостоятельных api-тестов.
Использовать HTTP-запросы можно в любом тесте в не зависимости от браузера. Но если не нужно выполнить только HTTP-запросы, то можно обойтись без запуска обычного браузера (например chrome или firefox) что значительно уменьшит время выполнения тестов. Для этого достаточно указать в качестве используемого браузера встроенный браузер http. Этот браузер умеет выполнять только запросы, по этому если в тесте будут ещё и обычные команды, то они будут пропущены (т.е. завершатся со статусом SKIPPED).
Механизм HTTP-запросов автоматически синхронизирует cookie текущего браузера с cookie запроса. Т.е. при отправки запроса используются cookie установленные для текущей браузерной сессии, а после завершении запроса они автоматически обновляются. Если нужно установить собственные cookie в запросе, то можно использовать команды для работы с cookies.
МЕТОД[ endpoint {, endpoint }, [ params ]]( инструкции запроса, [ ,content_type ] [ ,redirects ] [ ,timeout ] )[( { подстановка, } { параметр=значение } )]
Для описания запроса служат следующие команды: GET, POST, PUT, DELETE, PATCH, HEAD или OPTIONS они определяют используемый метод запроса. После указания метода нужно в квадратных скобках передают адрес запроса. Обычно адресом запроса является URL конкретного метода веб-api, но вместо неё можно передать список URL-строк. Такой список может быть возвращён кванторами ALL или ANY при выполнении браузерного тестирования. Запрос будет выполнен последовательно для каждого переданного URL.
Инструкции запроса служат для указания данных передаваемых в запросе и валидации его результата. Они будут выполнены для каждого запроса (т.е. для каждого URL указанного в endpoint). Порядок следования инструкций не важен.
Аргументы:
- endpoint - Адрес запроса.
- params - Словарь с url-параметрами запроса По умолчанию - {}
- content_type - Тип контента запроса (в настоящий момент поддерживается только JSON) По умолчанию - JSON
- redirects - Следовать перенаправлениями в запросе По умолчанию - False
- timeout - Максимальное время выполнения запроса. По умолчанию - CONFIG.HTTP_TIMEOUT
Пример:
TEST["Проверка доступности ссылок для скачивание файлов"](
URL("http://the-internet.herokuapp.com/download")
, "Проверяем доступность всех URL файлов"
, HEAD[ALL(".example > a", "attr::href")](
ASSERT(STATUS == 200)
, timeout=25
)
, test_id="download"
, tags = "files,download"
)Объекты запроса
Описания запросов являются самостоятельными объектами, они не обязательно должны быть определены внутри теста. За счёт этого один и тоже описание запроса может быть использовано в разных тестах и даже может быть помещено в пространства имён.
Пример:
scope = SCOPE("api")
token = {"user_name": "Meta", "password": "Test"}
# создаём описание запроса и помещаем его в пространство имён api/make_token
scope.make_token = POST["/Account/get_token"](
# валидация ответа сервера
STATUS == STATUS.OK
, CHECK_JSON_SHEMA("api/shema/token.json")
# устанавливаем переменную token как тело запроса
, PAYLOAD(token)
)
TEST["Проверяем получение токена авторизации"](
"scope::api/make_token" # Ссылка на пространство имён, можно заменить объектом NP("api", "make_token")
, tags="api"
, test_id="api_user"
)Используя существующий объект запроса можно создать его копию с изменённым адресом запроса (endpoint) или его параметрами (params). Для этого нужно вызвать объект запроса передав ему одну или несколько строк для подстановки в строку адреса и/или словарь параметров запроса. Переданные при вызове строки будут подставлены в строку адреса заменив в них шаблон вида { n } где n - индекс строки для подстановки. Кроме того возможен вариант подстановки с применением оператора интерполяции строк.
Пример:
# объект запроса для удаления пользователя
del_user = DELETE["/Account/User/{ 0 }"]( # в место { 0 } будет подставлен id пользователя
STATUS == STATUS.OK
)
...
# удаляем пользователя передав ему идентификатор и объекта запроса get_user
del_user(CONTENT(get_user)["user_id"])Инструкции запроса
STATUS | STATUS(запрос [ , cached ])
Возвращает статус-код ответа сервера. Может быть использована вне описания запроса, в этом случае первым аргументом нужно передать объект запроса у которого нужно получить код-статуса.
Аргумент cached может принимать следующие значения: True, False и None. Данные в любом случае будут возвращены из кэша, но True означает что возвращаемый результат будет взят только из кэша. False - что будет выполнен запрос к серверу, а полученный результат будет закэширован. None - если значение заголовка Cache-Control будет равно no-cache, то кэш будет инвалидирован (т.е. поведение аналогично значению False) иначе нет.
Аргументы:
- Запрос - Объект запроса для которого нужно вернуть код-статуса.
- cached - Режим инвалидации кэша (описан выше).
Для удобства определения кода-статуса в пространства имён команды STATUS были добавлены идентификаторы со следующими кодами:
| Код | Идентификатор | Код | Идентификатор | Код | Идентификатор |
|---|---|---|---|---|---|
| 100 | CONTINUE | 308 | PERMANENT_REDIRECT | 423 | LOCKED |
| 101 | SWITCHING_PROTOCOLS | 400 | BAD_REQUEST | 424 | FAILED_DEPENDENCY |
| 102 | PROCESSING | 401 | UNAUTHORIZED | 425 | TOO_EARLY |
| 103 | EARLY_HINTS | 402 | PAYMENT_REQUIRED | 426 | UPGRADE_REQUIRED |
| 200 | OK | 404 | NOT_FOUND | 428 | PRECONDITION_REQUIRED |
| 201 | CREATED | 405 | METHOD_NOT_ALLOWED | 429 | TOO_MANY_REQUESTS |
| 202 | ACCEPTED | 406 | NOT_ACCEPTABLE | 431 | REQUEST_HEADER_FIELDS_TOO_LARGE |
| 203 | NON_AUTHORITATIVE_INFORMATION | 407 | PROXY_AUTHENTICATION_REQUIRED | 451 | UNAVAILABLE_FOR_LEGAL_REASONS |
| 204 | NO_CONTENT | 408 | REQUEST_TIMEOUT | 500 | INTERNAL_SERVER_ERROR |
| 205 | RESET_CONTENT | 409 | CONFLICT | 501 | NOT_IMPLEMENTED |
| 206 | PARTIAL_CONTENT | 410 | GONE | 502 | BAD_GATEWAY |
| 207 | MULTI_STATUS | 411 | LENGTH_REQUIRED | 503 | SERVICE_UNAVAILABLE |
| 208 | ALREADY_REPORTED | 412 | PRECONDITION_FAILED | 504 | GATEWAY_TIMEOUT |
| 208 | ALREADY_REPORTED | 413 | REQUEST_ENTITY_TOO_LARGE | 505 | HTTP_VERSION_NOT_SUPPORTED |
| 300 | MULTIPLE_CHOICES | 414 | REQUEST_URI_TOO_LONG | 506 | VARIANT_ALSO_NEGOTIATES |
| 301 | MOVED_PERMANENTLY | 415 | UNSUPPORTED_MEDIA_TYPE | 507 | INSUFFICIENT_STORAGE |
| 302 | FOUND | 416 | REQUESTED_RANGE_NOT_SATISFIABLE | 508 | LOOP_DETECTED |
| 303 | SEE_OTHER | 417 | EXPECTATION_FAILED | 510 | NOT_EXTENDED |
| 304 | NOT_MODIFIED | 418 | IM_A_TEAPOT | 511 | NETWORK_AUTHENTICATION_REQUIRED |
| 305 | USE_PROXY | 421 | MISDIRECTED_REQUEST | ||
| 307 | TEMPORARY_REDIRECT | 422 | UNPROCESSABLE_ENTITY |
HEADERS | HEADERS(запрос, [ cached ])
Возвращает заголовки ответа сервера. Может быть использована вне описания запроса, в этом случае первым аргументом нужно передать объект запроса у которого нужно получить заголовки ответа.
Аргумент cached может принимать следующие значения: True, False и None. Данные в любом случае будут возвращены из кэша, но True означает что возвращаемый результат будет взят только из кэша. False - что будет выполнен запрос к серверу, а полученный результат будет закэширован. None - если значение заголовка Cache-Control будет равно no-cache, то кэш будет инвалидирован (т.е. поведение аналогично значению False) иначе нет.
Аргументы:
- Запрос - Объект запроса для которого нужно вернуть заголовки ответа.
- cached - Режим инвалидации кэша (описан выше).
Заголовки ответа представляют собой словарь доступ к значениям которого можно получить как через обращение к атрибуту объекта, так и через обращение к его ключу.
Пример:
TEST["Параметры GET запроса"](
GET["https://postman-echo.com/get", {"foo1": "bar3", "foo2": "bar2"}](
HEADERS < "Server" # ключ Server содержится в заголовках
, HEADERS["Server"] == "cloudflare" # проверка значения ключа Server (обращение к ключу объекта)
, HEADERS.Server == "cloudflare" # тоже самое, но через обращение к атрибуту
)
, browser="http"
, test_id="get_param"
)CONTENT | CONTENT(запрос, [ cached ])
Возвращает тело ответа сервера. Может быть использована вне описания запроса, в этом случае первым аргументом нужно передать объект запроса у которого нужно получить тело ответа.
Аргумент cached может принимать следующие значения: True, False и None. Данные в любом случае будут возвращены из кэша, но True означает что возвращаемый результат будет взят только из кэша. False - что будет выполнен запрос к серверу, а полученный результат будет закэширован. None - если значение заголовка Cache-Control будет равно no-cache, то кэш будет инвалидирован (т.е. поведение аналогично значению False) иначе нет.
Аргументы:
- Запрос - Объект запроса для которого нужно вернуть тело ответа.
- cached - Режим инвалидации кэша (описан выше).
Пример:
# запрос получения списка книг текущего пользователя
books = GET["/books/all_books"](
STATUS == STATUS.OK
, CHECK_JSON_SHEMA("api/shema/books/all_books.json")
)
# получаем список всех ISBN
isbn = CONTENT(books)["books"]["isbn"]
TEST["Все книги"](
"В коллекции книг есть книги у которых определён ISBN"
, COUNT(isbn) > 0
)PAYLOAD(body)
Добавляет данные в тело запроса. Если атрибут запроса content_type равен JSON, то в качестве тела запроса должен быть передан словарь, иначе текстовые данные.
Аргументы:
- body - Тело запроса.
Пример:
TEST["Добавляем книгу в коллекцию пользователя"](
POST["/user/books"](
STATUS == 201
, PAYLOAD({
"userId": "scope::api/user_id"
, "collectionOfIsbns": [{"isbn": "978-5-699-12014-7"}]
}))
, tags="api"
)HEADER_SET(заголовок=значение)
Добавляет заголовок в запрос.
Аргументы:
- заголовок - Наименование заголовка.
- значение - Значение заголовка.
Пример:
TEST["Параметры GET запроса"](
GET["https://postman-echo.com/get", {"foo1": "bar3", "foo2": "bar2"}](
HEADER_SET(hlp=5, hlp2=3) # устанавливаем заголовки "hlp" и "hlp2"
, CONTENT["headers"].hlp == 5 # тело ответа содержит все переданные заголовки
, CONTENT.headers["hlp2"] == 3 # по этому мы можем проверить их значение через объект CONTENT
))Аутентификация
AUTH_BEARER(access_token)
Добавляет токен для аутентификации через JWT-токены.
Аргументы:
- access_token - Токен для аутентификации.
Пример:
# объект запроса получения токена
get_token = POST["/account/get_token"](
STATUS == STATUS.OK
, PAYLOAD({"user_name": "Meta", "password": "Test"})
)
TEST["Проверка запроса одной книги"](
AUTH_BEARER(CONTENT(get_token)["token"]) # получаем и устанавливаем ключ аутентификации, он будет действовать весь тест
, POST["/books/book", {"isbn": "9785699120147"}](
STATUS == 200
, CHECK_JSON_SHEMA("api/shema/books/one_book.json")
))AUTH_BASE(user, passwd)
Команда реализует базовую аутентификацию.
Аргументы:
- user - Логин пользователя.
- passwd - Пароль пользователя.
Пример:
TEST["Базовая авторизация"](
AUTH_BASE("postman", "password")
, GET["https://postman-echo.com/basic-auth"](
STATUS == STATUS.OK
, CONTENT["authenticated"] == True
))Триггеры и аутентификация
Для аутентификации можно использовать триггеры. В примере приведённом ниже:
- создаётся тестовый пользователь (метод setup)
- перед запуском каждого теста производится авторизация при помощи команды AUTH_BEARER (метод setup_test)
- после завершения всех тестов удаляется тестовый пользователь (метод close)
Пример:
token = {"user": "Meta", "passwd": "Test"}
make_token = POST["/account/get_token"](
STATUS == STATUS.OK
, CHECK_JSON_SHEMA("api/shema/token.json")
, PAYLOAD(token)
)
del_user = DELETE["/account/user/{ 0 }"](
STATUS == STATUS.OK
)
class AuthTrigger(BaseTrigger):
def setup(self):
return (
"Создаём тестового пользователя"
, POST["/account/user"](
STATUS > {STATUS.CREATED, STATUS.NOT_ACCEPTABLE}
, PAYLOAD(token)
))
def setup_test(self, browser, test_id, test_scope, test_args):
# Авторизация пользователя
return AUTH_BEARER(CONTENT(make_token).token)
def close(self):
return (
"Удаляем тестового пользователя"
, AUTH_BEARER(CONTENT(make_token)["token"])
, del_user(CONTENT(make_token)["userId"])
)
CONFIG.TRIGGER = AuthTriggerДля версии 2.0 редакция от 16.09.2026