Тестирование API
Так же, как мы тестировали веб-сайт, Codeception позволяет вам тестировать веб-сервисы. Их очень сложно тестировать вручную, поэтому автоматизация тестирования веб-сервисов — очень хорошая идея. У нас есть стандарты SOAP и REST, которые представлены в соответствующих модулях, которые мы рассмотрим в этой главе.
Вы должны начать с создания нового набора тестов (который не был предоставлен командой bootstrap). Мы рекомендуем назвать его api и использовать класс ApiTester для него.
php vendor/bin/codecept generate:suite api
Мы поместим туда все тесты api.
REST API
ПРИМЕЧАНИЕ: Для тестирования REST API необходимо установить пакет
codeception/module-rest.
Доступ к REST веб-сервису осуществляется через HTTP со стандартными методами: GET, POST, PUT, DELETE. Они позволяют пользователям получать и манипулировать сущностями из сервиса. Для доступа к WebService требуется HTTP-клиент, поэтому для его использования вам нужен модуль PhpBrowser или один из модулей фреймворка. Например, мы можем использовать модуль Symfony для приложений Symfony2, чтобы проигнорировать веб-сервер и протестировать веб-сервис внутри.
Настройка модулей в api.suite.yml:
actor: ApiTester
modules:
enabled:
- REST:
url: http://serviceapp/api/v1/
depends: PhpBrowser Модуль REST подключится к PhpBrowser в соответствии с этой конфигурацией. В зависимости от веб-сервиса мы можем иметь дело с ответами в формате XML или JSON. Codeception хорошо обрабатывает оба формата данных, однако, если вам не нужен один из них, вы можете явно указать, что будут использоваться JSON или XML части модуля:
actor: ApiTester
modules:
enabled:
- REST:
url: http://serviceapp/api/v1/
depends: PhpBrowser
part: Json Тесты API могут быть функциональными и выполняться с использованием Symfony, Laravel5, Zend или любого другого модуля фреймворка. Вам потребуется немного обновить конфигурацию для этого:
actor: ApiTester
modules:
enabled:
- REST:
url: /api/v1/
depends: Laravel5 После настройки нового набора тестов мы можем создать первый пример теста:
php vendor/bin/codecept generate:cest api CreateUser
Он будет называться CreateUserCest.php. Нам нужно реализовать общедоступный метод для каждого теста. Давайте сделаем createUserViaAPI для тестирования создания пользователя через REST API.
<?php
class CreateUserCest
{
// tests
public function createUserViaAPI(\ApiTester $I)
{
$I->amHttpAuthenticated('service_user', '123456');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPost('/users', [
'name' => 'davert',
'email' => 'davert@codeception.com'
]);
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseContains('{"result":"ok"}');
}
} Мы можем использовать константы кодов HTTP из Codeception\Util\HttpCode вместо числовых значений для проверки кода ответа в методах seeResponseCodeIs и dontSeeResponseCodeIs.
Давайте посмотрим, из чего состоит тест.
Авторизация
Для авторизации запросов к внешним ресурсам поставщик обычно требует авторизации с помощью заголовков. Дополнительные заголовки можно задать перед запросом с помощью команды haveHttpHeader:
<?php
$I->haveHttpHeader('api_key', 'special-key'); Для общих схем авторизации используйте один из следующих методов:
amAWSAuthenticatedamBearerAuthenticatedamDigestAuthenticatedamHttpAuthenticatedamNTLMAuthenticated
Отправка запросов
Действительное действие в тесте происходит только при отправке запроса. Перед запросом вы можете предоставить дополнительные HTTP-заголовки, которые будут использоваться в последующем запросе для установки авторизации или ожидаемого формата содержимого.
<?php
$I->haveHttpHeader('accept', 'application/json');
$I->haveHttpHeader('content-type', 'application/json'); После установки заголовков вы можете отправить запрос. Для получения данных используйте sendGet:
<?php
// pass in query params in second argument
$I->sendGet('/posts', [ 'status' => 'pending' ]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
sendGetне вернет никакого значения. Однако вы можете получить доступ к данным из ответа и выполнить утверждения, используя другие доступные методы модуля REST.
Для создания или обновления данных вы можете использовать другие общие методы:
sendPostsendPutsendDeletesendPatch
Валидация структуры JSON
Если ожидается получение ответа в формате JSON, мы можем проверить его структуру с помощью JSONPath. Он похож и звучит как XPath, но предназначен для работы с данными JSON, однако мы можем преобразовать JSON в XML и использовать XPath для проверки структуры. Оба подхода допустимы и могут использоваться в модуле REST:
<?php
$I->sendGet('/users');
$I->seeResponseCodeIs(HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseJsonMatchesJsonPath('$[0].user.login');
$I->seeResponseJsonMatchesXpath('//user/login'); Более подробную проверку можно применить, если вам нужно валидировать тип полей в ответе. Вы можете сделать это, используя действие seeResponseMatchesJsonType, в котором вы определяете структуру JSON ответа.
<?php
$I->sendGet('/users/1');
$I->seeResponseCodeIs(HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseMatchesJsonType([
'id' => 'integer',
'name' => 'string',
'email' => 'string:email',
'homepage' => 'string:url|null',
'created_at' => 'string:date',
'is_active' => 'boolean'
]); Codeception использует этот простой и легкий формат определений, который можно легко изучить и расширить.
Получение данных из ответов
Когда вам нужно получить значение из ответа и использовать его в последующих запросах, вы можете использовать методы grab*. Например, использование grabDataFromResponseByJsonPath позволяет запросить значение JSON.
<?php
list($id) = $I->grabDataFromResponseByJsonPath('$.id');
$I->sendGet('/pet/' . $id); Валидация данных JSON-ответов
Последняя строка предыдущего примера проверяла, содержал ли ответ предоставленную строку. Однако мы не должны полагаться на это, так как в зависимости от форматирования содержимого мы можем получать разные результаты с теми же данными. На самом деле нам нужно проверить, что ответ может быть распарсен и содержит некоторые ожидаемые значения. В случае JSON мы можем использовать метод seeResponseContainsJson
<?php
// matches {"result":"ok"}'
$I->seeResponseContainsJson(['result' => 'ok']);
// it can match tree-like structures as well
$I->seeResponseContainsJson([
'user' => [
'name' => 'davert',
'email' => 'davert@codeception.com',
'status' => 'inactive'
]
]); Вы можете выполнить еще более сложные утверждения относительно ответа. Это можно сделать, написав свои собственные методы в классах помощников. Для доступа к последнему JSON-ответу вам нужно получить свойство response модуля REST. Давайте продемонстрируем это с помощью метода seeResponseIsHtml:
<?php
namespace Helper;
class Api extends \Codeception\Module
{
public function seeResponseIsHtml()
{
$response = $this->getModule('REST')->response;
$this->assertRegExp('~^<!DOCTYPE HTML(.*?)<html>.*?<\/html>~m', $response);
}
} Аналогичным образом вы можете получить параметры и заголовки запроса.
Тестирование XML-ответов
В случае, если ваш REST API работает с форматом XML, вы можете использовать аналогичные методы для тестирования его данных и структуры. Существует метод seeXmlResponseIncludes для проверки включения частей XML в ответ, и метод seeXmlResponseMatchesXpath для проверки его структуры.
<?php
$I->sendGet('/users.xml');
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseIsXml();
$I->seeXmlResponseMatchesXpath('//user/login');
$I->seeXmlResponseIncludes(\Codeception\Util\Xml::toXml([
'user' => [
'name' => 'davert',
'email' => 'davert@codeception.com',
'status' => 'inactive'
]
])); Мы используем класс Codeception\Util\Xml, который позволяет создавать XML-структуры чистым способом. Метод toXml может принимать строку или массив и возвращать экземпляр \DOMDocument. Если ваш XML содержит атрибуты и поэтому не может быть представлен как массив PHP, вы можете создать XML с помощью класса XmlBuilder. Мы подробнее рассмотрим его в следующей секции.
Используйте
\Codeception\Util\Xml::build()для создания экземпляра XmlBuilder.
SOAP API
SOAP веб-сервисы обычно более сложные. Вам потребуется PHP с поддержкой SOAP. Также требуются хорошие знания XML. Модуль SOAP использует специально отформатированный POST-запрос для подключения к веб-сервисам WSDL. Codeception использует PhpBrowser или один из модулей фреймворка для выполнения взаимодействий. Если вы выберете использование модуля фреймворка, SOAP будет автоматически подключаться к основному фреймворку. Это может улучшить скорость выполнения тестов и предоставит вам более подробные трассировки стека.
Давайте настроим модуль SOAP для использования с PhpBrowser:
actor: ApiTester
modules:
enabled:
- SOAP:
depends: PhpBrowser
endpoint: http://serviceapp/api/v1/ SOAP-запрос может содержать информацию, специфичную для приложения, например, аутентификацию или платеж. Эта информация предоставляется в заголовке SOAP внутри элемента <soap:Header> XML-запроса. Если вам нужно отправить такой заголовок, вы можете использовать действие haveSoapHeader. Например, следующая строка кода
<?php
$I->haveSoapHeader('Auth', ['username' => 'Miles', 'password' => '123456']); произведёт этот XML-заголовок
<soap:Header> <Auth> <username>Miles</username> <password>123456</password> </Auth> </soap:Header>
Используйте метод sendSoapRequest для определения тела запроса.
<?php
$I->sendSoapRequest('CreateUser', '<name>Miles Davis</name><email>miles@davis.com</email>'); Этот вызов будет преобразован в XML:
<soap:Body> <ns:CreateUser> <name>Miles Davis</name> <email>miles@davis.com</email> </ns:CreateUser> </soap:Body>
И вот список примеров утверждений, которые можно использовать с SOAP.
<?php
$I->seeSoapResponseEquals('<?xml version="1.0"<error>500</error>');
$I->seeSoapResponseIncludes('<result>1</result>');
$I->seeSoapResponseContainsStructure('<user><name></name><email></email>');
$I->seeSoapResponseContainsXPath('//result/user/name[@id=1]'); Если вы не хотите писать длинные XML-строки, рассмотрите использование класса XmlBuilder. Он поможет вам создавать сложные XML-структуры в стиле jQuery. В следующем примере мы будем использовать XmlBuilder вместо обычного XML.
<?php
$I->haveSoapHeader('Session', array('token' => '123456'));
$I->sendSoapRequest('CreateUser', Xml::build()
->user->email->val('miles@davis.com'));
$I->seeSoapResponseIncludes(\Codeception\Util\Xml::build()
->result->val('Ok')
->user->attr('id', 1)
); Вам решать, использовать ли XmlBuilder или обычный XML. XmlBuilder также вернёт XML-строку.
Вы можете расширить текущую функциональность, используя модуль SOAP в классе помощника. Для доступа к SOAP-ответу как \DOMDocument вы можете использовать свойство response модуля SOAP.
<?php
namespace Helper;
class Api extends \Codeception\Module {
public function seeResponseIsValidOnSchema($schema)
{
$response = $this->getModule('SOAP')->response;
$this->assertTrue($response->schemaValidate($schema));
}
} Заключение
Codeception имеет два модуля, которые помогут вам тестировать различные веб-сервисы. Для них необходимо создать новый набор тестов api. Помните, вы не ограничены тестированием только тела ответа. Включив модуль Db, вы можете проверить, был ли пользователь создан после вызова CreateUser. Вы можете улучшить сценарии тестирования, используя ответы REST или SOAP в методах помощников.
- Следующая глава: Codecoverage >
- Предыдущая глава: < Данные
© 2011 Michael Bodnarchuk and contributors
Licensed under the MIT License.
https://codeception.com/docs/10-APITesting