Установка

Установите Composer в корень вашего проекта. Выполните команду:

composer require "codeception/codeception:*"

С этого момента Codeception может быть запущен как:

vendor/bin/codecept

Инициализируйте тестовое окружение следующей командой:

vendor/bin/codecept bootstrap

Введение

Идея тестирования не нова. Вы не сможете спокойно спать если не будете уверены в том, что Ваш последний коммит не поломал все приложение. Покрытие приложения тестами дает Вам большую уверенность в стабильности кода. Этого достаточно!

Существует множество подходов к тестированию приложений. Самым популярным является "Модульное тестирование" Unit Testing. В случае веб-приложений, тестирование моделей и контроллеров в изоляции друг от друга не гарантирует работоспособность всего приложения. Для полной проверки приложения Вы должны написать функциональные (functional) и/или приемочные (acceptance) тесты.

Codeception - фреймворк для тестирования разделяет эти категории тестов. Прямо из коробки Вы получаете возможность писать модульные (unit), функциональные (functional) и приемочные (acceptance) тесты в едином стиле.

Давайте рассмотрим перечисленные категории тестов.

Приемочные тесты (WebGuy)

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

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

Для написания и выполнения приемочных тестов, Codeception эмулирует работу браузера благодаря Mink. Конечно, для этого можно было бы использовать такие инструменты как Selenium, но Codeception и Mink более гибкие и лучше подходят для подобных тестов.

Пожалуйста, запомните! Абсолютно любой проект может быть покрыт приемочными тестами, даже если Вы используете очень специфичную CMS и/или фреймворк.

Простой приемочный тест:

$I = new WebGuy($scenario);
$I->amOnPage('/');
$I->click('Sign Up');
$I->submitForm('#signup', array('username' => 'orkhanalyshov', 'email' => 'orkhanalyshov@gmail.com'));
$I->see('Thank you for Signing Up!');

- Достоинства:

  • можно протестировать абсолютно любой проект
  • можно протестировать javascript и ajax-запросы
  • можно показать работу тестов менеджерам и клиентам
  • простота и стабильность: меньшая зависимость от изменений в исходном коде и технологиях

- Недостатки:

  • тесты могу приводить к ложно-положительным результатам
  • приемочные тесты медленные: требуют запуск браузера и обновления базы данных

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

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

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

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

Простой функциональный тест:

$I = new TestGuy($scenario);
$I->amOnPage('/');
$I->click('Sign Up');
$I->submitForm('#signup', array('username' => 'orkhanalyshov', 'email' => 'orkhanalyshov@gmail.com'));
$I->see('Thank you for Signing Up!');
$I->seeEmailSent('orkhanalyshov@gmail.com', 'Thank you for registration');
$I->seeInDatabase('users', array('email' => 'orkhanalyshov@gmail.com'));

- Достоинства:

  • как и у приемочных тестов, но значительно быстрее
  • предоставляют больше информации об ошибках
  • код тестов все еще можно показать менеджерам и/или клиентам
  • стабильность: только глобальное изменение кода или смена фреймворка может сломать их

- Недостатки:

  • невозможно тестировать javascript и ajax-запросы
  • эмулируя работу браузера тесты могут приводить к ложно-положительным результатам
  • требуется фреймворк

Модульное тестирование (CodeGuy)

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

Главное отличие модульных (unit) и интеграционных (integration) тестов заключается в том, что модульные тесты должны запускать в полной изоляции. Все остальные классы и методы должны быть заменены на "stubs".

Codeception основан на PHPUnit. Если у Вас есть опыт написания модульных тестов на PHPUnit - Вы можете продолжать писать их. Codeception легко и просто запускает такие тесты.

Однако, Codeception предоставляет ряд инструментов, которые сделают Ваши модульные тесты простыми и классными! Даже не очень опытные разработчики должны понимать что именно тестируется и как. Требования и код могут меняться очень быстро, при этом каждый раз должны меняться и unit-тесты чтобы всегда соответствовать требованиям. Чем лучше Вы понимаете сценарий тестирования, тем быстрее Вы сможете изменить его под новые требования.

Простой моудльный тест:

$I = new CodeGuy($scenario);
$I->testMethod('User.update');
$I->haveStubClass($unit = Stub::make('User'));
$I->dontSeeInDatabase('users', array('id' => 1, 'username' => 'orkhanalyshov'));
$I->executeTestedMethodOn($unit, 1, array('username' => 'orkhanalyshov'));
$I->seeMethodInvoked($unit, 'save');
$I->seeInDatabase('users', array('id' => 1, 'username' => 'orkhanalyshov'));

- Достоинства:

  • очень быстрые
  • могут покрывать редко используемый функционал
  • могут проверять стабильность ядра приложения

- Недостатки:

  • не позволяют тестировать взаимодействие между отдельными модулями
  • нестабильны: реагируют на любое изменение кода

Заключение

Не смотря на большую популярность TDD, совсем не многие PHP-разработчики пишут тесты для своих приложений. Codeception был разработан, чтобы сделать написание тестов простым и веселым занятием! Codeception позволяет писать модульные, интеграционные, функциональные и приемочные тесты в едином стиле.

Codeception можно назвать BDD-фреймворком. Все Codeception-тесты пишутся в описательной форме. Просто просмотрев код теста, Вы легко сможете понять, что и как он тестирует. Даже сложные тесты с множеством проверок пишутся на простом и понятном PHP DSL.