Spec-Zone.ru › Codeception

Функциональные тесты

Теперь, когда мы написали некоторые приемочные тесты, функциональные тесты почти такие же, с одним важным отличием: функциональные тесты не требуют веб-сервера.

Под капотом Codeception использует BrowserKit Symfony для «отправки» запросов к вашему приложению. Таким образом, реальный HTTP-запрос не выполняется, а вместо этого в контроллер фреймворка (передним) передается объект Request BrowserKit с необходимыми свойствами.

В качестве первого шага вам необходимо включить модуль Codeception для вашего фреймворка в functional.suite.yml (см. ниже).

Все модули фреймворка Codeception разделяют один и тот же интерфейс, и, следовательно, ваши тесты не привязаны ни к одному из них. Вот пример функционального теста:

<?php
// LoginCest.php

class LoginCest
{
    public function tryLogin(FunctionalTester $I)
    {
        $I->amOnPage('/');
        $I->click('Login');
        $I->fillField('Username', 'Miles');
        $I->fillField('Password', 'Davis');
        $I->click('Enter');
        $I->see('Hello, Miles', 'h1');
        // $I->seeEmailIsSent(); // only for Symfony
    }
}

Как видите, синтаксис одинаков для функциональных и приемочных тестов.

Ограничения

Функциональные тесты обычно намного быстрее, чем приемочные тесты. Но функциональные тесты менее стабильны, так как они запускают Codeception и приложение в одной среде. Если ваше приложение не было разработано для работы в долгоживущих процессах (например, если вы используете оператор exit или глобальные переменные), то функциональные тесты, вероятно, не для вас.

Заголовки, куки, сессии

Одна из распространенных проблем с функциональными тестами — использование функций PHP, которые работают с заголовками, сессиями и куками. Как вы, возможно, уже знаете, функция header вызывает ошибку, если она выполняется после того, как PHP уже вывел что-то. В функциональных тестах приложение запускается несколько раз, поэтому мы получим много нерелевантных ошибок в результате.

Внешние URL-адреса

Функциональные тесты не могут получить доступ к внешним URL-адресам, только к URL-адресам внутри вашего проекта. Вы можете использовать PhpBrowser для открытия внешних URL-адресов.

Общий доступ к памяти

При функциональном тестировании, в отличие от запуска приложения традиционным способом, приложение PHP не останавливается после завершения обработки запроса. Поскольку все запросы выполняются в одном контейнере памяти, они не изолированы. Поэтому если вы видите, что ваши тесты загадочно терпят неудачу, когда этого не должно быть — попробуйте выполнить один тест. Это покажет, терпят ли тесты неудачу из-за того, что они не были изолированы во время выполнения. Держите память чистой, избегайте утечек памяти и очищайте глобальные и статические переменные.

Включение модулей фреймворка

У вас есть набор функциональных тестов в каталоге tests/functional. Для начала необходимо включить один из модулей фреймворка в файл конфигурации набора: tests/functional.suite.yml.

Symfony

Для выполнения интеграции Symfony вам просто нужно включить модуль Symfony в ваш набор тестов. Если вы также используете Doctrine2, не забудьте включить его тоже. Чтобы модуль Doctrine2 подключался с помощью службы doctrine из Symfony, вы должны указать модуль Symfony как зависимость для Doctrine2:

# functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - Symfony
        - Doctrine2:
            depends: Symfony # connect to Symfony

По умолчанию этот модуль будет искать AppKernel в каталоге app.

Модуль использует Symfony Profiler для предоставления дополнительной информации и утверждений.

См. полную справку

Laravel5

Модуль Laravel5 включен и не требует конфигурации:

# functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - Laravel5

Yii2

Тесты Yii2 включены в шаблоны приложений Basic и Advanced. Следуйте руководствам Yii2 для начала.

Zend Framework 2

Используйте модуль ZF2 для запуска функциональных тестов внутри Zend Framework 2:

# functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - ZF2

Zend Expressive

Zend Expressive тесты могут быть выполнены при включении соответствующего модуля.

# functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - ZendExpressive

См. справочник по модулям для получения дополнительных параметров конфигурации

Phalcon 4

Модуль Phalcon4 требует создания файла bootstrap, который возвращает экземпляр \Phalcon\Mvc\Application. Чтобы начать написание функциональных тестов с поддержкой Phalcon, вы должны включить модуль Phalcon4 и указать путь к этому файлу bootstrap:

# functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - Phalcon4:
            bootstrap: 'app/config/bootstrap.php'
             cleanup: true
             savepoints: true

См. полную справку

Написание функциональных тестов

Функциональные тесты пишутся так же, как и Приемочные тесты с включенным модулем PhpBrowser. Все модули фреймворка и модуль PhpBrowser разделяют одни и те же методы и один и тот же движок.

Поэтому мы можем открыть веб-страницу с помощью метода amOnPage:

<?php
$I->amOnPage('/login');

Мы можем нажимать ссылки для открытия веб-страниц:

<?php
$I->click('Logout');
// click link inside .nav element
$I->click('Logout', '.nav');
// click by CSS
$I->click('a.logout');
// click with strict locator
$I->click(['class' => 'logout']);

Мы также можем отправлять формы:

<?php
$I->submitForm('form#login', ['name' => 'john', 'password' => '123456']);
// alternatively
$I->fillField('#login input[name=name]', 'john');
$I->fillField('#login input[name=password]', '123456');
$I->click('Submit', '#login');

И выполнять утверждения:

<?php
$I->see('Welcome, john');
$I->see('Logged in successfully', '.notice');
$I->seeCurrentUrlEquals('/profile/john');

Модули фреймворка также содержат дополнительные методы для доступа к внутренним компонентам фреймворка. Например, модули Laravel5, Phalcon и Yii2 имеют метод seeRecord, который использует слой ActiveRecord для проверки того, что запись существует в базе данных.

Посмотрите полную справку по используемому модулю. Большинство его методов являются общими для всех модулей, но некоторые из них уникальны.

Вы также можете получить доступ к глобальным переменным фреймворка внутри теста или получить доступ к контейнеру внедрения зависимостей внутри класса Helper\Functional:

<?php
namespace Helper;

class Functional extends \Codeception\Module
{
    function doSomethingWithMyService()
    {
        $service = $this->getModule('Symfony')->grabServiceFromContainer('myservice');
        $service->doSomething();
    }
}

Также проверьте все доступные Публичные свойства используемых модулей для получения полного доступа к их данным.

Отчет об ошибках

По умолчанию Codeception использует уровень отчета об ошибках E_ALL & ~E_STRICT & ~E_DEPRECATED. В функциональных тестах вы можете изменить этот уровень в зависимости от политики обработки ошибок вашего фреймворка. Уровень отчета об ошибках можно установить в файле конфигурации набора:

actor: FunctionalTester
...
error_level: E_ALL & ~E_STRICT & ~E_DEPRECATED

error_level также можно установить глобально в файле codeception.yml. Для этого необходимо указать error_level в качестве части settings. Дополнительную информацию см. в Глобальной конфигурации. Обратите внимание, что значение error_level для конкретного набора тестов переопределит глобальное значение.

Заключение

Функциональные тесты отлично подходят, если вы используете мощные фреймворки. Используя функциональные тесты, вы можете получить доступ и манипулировать их внутренним состоянием. Это делает ваши тесты короче и быстрее. В других случаях, если вы не используете фреймворки, нет практической причины для написания функциональных тестов. Если вы используете фреймворк, отличный от перечисленных здесь, создайте для него модуль и поделитесь им с сообществом.

  • Следующая глава: UnitTests >
  • Предыдущая глава: < Приемочные тесты

© 2011 Michael Bodnarchuk and contributors
Licensed under the MIT License.
https://codeception.com/docs/04-FunctionalTests

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API