Тестирование Веб Сервисов

Точно так же, как Вы тестируете свой сайт, Codeception позволяет тестировать веб сервисы. Достаточно сложно тестировать их вручную, поэтому автоматизация тестирования, в данном случае, является достаточно хорошей идеей. В Codeception имеется поддержка двух стандартов, SOAP и REST, представленных соответствующими модулями, которые и будут рассмотрены в данной статье.

Для начала Вам необходимо создать новый тестовый набор, который не предоставляется командой bootstrap. Мы рекомендуем назвать его api и использовать для него класс ApiGuy.

$ php codecept.phar generate:suite api ApiGuy

Там мы будем вставлять все наши api тесты.

REST

REST веб сервис работает через HTTP используя стандартные методы: GET, POST, PUT (PATCH), DELETE. Они позволяют получить и управлять данными сервиса. Использование веб сервисов требует наличия HTTP клиента, таким образом, Вам необходим модуль PhpBrowser или один из настроенных модулей доступных фреймворков. К примеру, мы можем использовать модуль Symfony2 для Symfony2 приложений с целью игнорирования веб сервера и тестирования веб сервиса изнутри.

Конфигурация модулей в api.suite.yml:

class_name: ApiGuy
modules:
    enabled: [PhpBrowser, REST, ApiHelper]
    config:
        PhpBrowser:
            url: http://serviceapp/
        REST:
            url: http://serviceapp/api/v1/

Модуль REST автоматически подключится к PhpBrowser. В случае использования Symfony2, Zend, или модулей других фреймворков, он будет подключаться к ним.

Не забудьте выполнить команду build после того, как закончите редактировать конфигурацию.

Создадим первый простой тест:

php codecept.phar generate:cept api CreateUser

Назовем его CreateUserCept.php. Будем использовать его для создания пользователя используя веб сервис:

<?php
$I = new ApiGuy($scenario);
$I->wantTo('create a user via API');
$I->amHttpAuthenticated('service_user','123456');
$I->haveHttpHeader('Content-Type','application/x-www-form-urlencoded');
$I->sendPOST('users', array('name' => 'davert', 'email' => 'davert@codeception.com'));
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
$I->seeResponseContains('{result: ok}');
?>

Модуль REST разработан для использования с сервисами, оперирующими данными в JSON формате. К примеру, метод seeResponseContainsJson конвертирует указанный массив в json и проверит его наличие в ответе от сервиса.

Возможно, Вам захочется использовать более сложные утверждения assertions для проверки ответов. Это может быть реализовано с помощью написания собственных методов в клаccах Helper. Для доступа к последнему JSON ответу Вам необходимо получить свойство response модуля REST. Продемонстрируем это на примере метода seeResponseIsHtml:

<?php
class ApiHelper extends \Codeception\Module {

    public function seeResponseIsHtml()
    {
        $response = $this->getModule('REST')->response;
        \PHPUnit_Framework_Assert::assertRegex('^<html>.*?<\/html>$', $response);
    }
}
?>

Точно так же Вы можете передавать параметры запроса и заголовки.

SOAP

Веб сервисы SOAP являются более сложным случаем. Вам необходим PHP собранный с поддержкой SOAP. Кроме того, необходимо хорошее знание XML. SOAP модуль использует специально форматированный POST запрос для подключения к WSDL веб сервисам. Codeception использует PhpBrowser или один из модулей фреймворков для реализации данного взаимодействия. Если Вы решите использовать один из модулей фреймворков, модуль SOAP будет автоматически подключен к фреймворку и вы сможете увеличить скорость выполнения тестов, а так же получить более детализированную трассировку и вывод.

Сконфигурируем модуль SOAP для использования с PhpBrowser:


class_name: ApiGuy
modules:
    enabled: [PhpBrowser, SOAP, ApiHelper]
    config:
        PhpBrowser:
            url: http://serviceapp/
        SOAP:
            endpoint: http://serviceapp/api/v1/

Запрос SOAP может содержать специфическую для приложения информацию, к примеру, информацию об аутентификации или об оплате. Эта информация обеспечивается SOAP заголовком внутри элемента <soap:Header> XML запроса. В случае, если Вам нужно сгенерировать такой заголовок, Вы можете использовать метод haveSoapHeader. К примеру, следующая строка кода:

<?php
$I->haveSoapHeader('Auth', array('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 (созданного с помощью фабрики SoapUtils) вместо использования XML:

<?php
use \Codeception\Utils\Soap;
$I = new ApiGuy($scenario);
$I->wantTo('create user');
$I->haveSoapHeader('Session', array('token' => '123456'));
$I->sendSoapRequest('CreateUser', Soap::request()->user->email->val('miles@davis.com'));
$I->seeSoapResponseIncludes(Soap::response()
    ->result->val('Ok')
        ->user->attr('id', 1)
);
?>

Решение о том, что использовать, XmlBuilder или XML строки, остается за вами. XmlBuilder возвращает XML строки, как Вы уже могли заметить.

Вы можете расширить существующую функциональность при помощи использования модуля SOAP в Вашем классе помощнике. Для доступа к такому SOAP ответу, как \DOMDocument, Вы можете использовать свойство response модуля SOAP:

<?php
class ApiHelper extends \Codeception\Module
{
    public function seeResponseIsValidOnSchema($schema)
    {
        $response = $this->getModule('SOAP')->response;
        $this->assertTrue($response->schemaValidate($schema));
    }
}
?>

Заключение

Codeception имеет два модуля позволяющих тестировать большинство веб сервисов. Для тестирования необходимо создать новый набор тестов api. Помните, что Вы не ограничены в том, чтобы тестировать только тело ответа. Например, включив модуль Db, Вы можете проверить, был ли создан пользователь после вызова CreateUser. Вы можете улучшить тестовые сценарии используя REST или SOAP ответы в своих методах помощников.

Трудились и переводили ребята из amyLabs