Введение

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

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

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

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

Приемочные тесты

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

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

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

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

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

Достоинства

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

Недостатки

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

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

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

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

Для функциональных тестов приложение должно быть готово к работе в режиме тестирования. Для таких фреймворков как Symfony2, Symfony1, или Zend - это не проблема.

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

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

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

Достоинства

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

Недостатки

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

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

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

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

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

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

простой интеграционный тест

<?php
function testSavingUser()
{
     $user = new User();
     $user->setName('Miles');
     $user->setSurname('Davis');
     $user->save();
     $this->assertEquals('Miles Davis', $user->getFullName());
     $this->codeGuy->seeInDatabase('users', array('name' => 'Miles', 'surname' => 'Davis'));
}
?>

Достоинства

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

Недостатки

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

Заключение

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

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

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