В данном разделе мы рассмотрим некоторые техники и опции, использование которых поможет Вам улучшить Ваши навыки в тестировании и сохранить качественную организацию Вашего проекта.
Интерактивная консоль добавлена для опробования команд Codeception перед тем, как они будут выполнены внутри тестов. Данная возможность была анонсирована начиная с версии 1.6.0.
Вы можете запустить консоль с помощью команды:
php codecept.phar console suitename
Теперь Вы можете выполнять любые команды соответствующего Guy-класса
и сразу же видеть результаты их выполнения. Это особенно полезно в случае работы с модулями Selenium. Запуск Selenium и браузера для тестирования обычно занимает довольно продолжительное время. Однако при использовании консоли Вы можете попробовать разнообразные селекторы и команды, после чего сможете быть уверенны в том, что написанный Вами тест выполнится.
Полезный совет: покажите начальству как резво Вы манипулируете веб страницами с помощью консоли и Selenium. Вы сможете убедить его в том, что довольно просто автоматизировать подобные вещи и начать использовать приемочное тестирование в проекте.
Если у Вас есть несколько проектов, содержащих Coeception тесты, Вы можете использовать один codecept.phar
файл для их запуска. Чтобы запускать Codeception из других директорий, добавляйте опцию -c
к любой Codeception команде кроме bootstrap
.
php codecept.phar run -c ~/projects/ecommerce/
php codecept.phar run -c ~/projects/drupal/
php codecept.phar generate:cept acceptance CreateArticle -c ~/projects/drupal/
Для создания проекта в директории отличной от той, где Вы находитесь, просто добавьте ее путь как параметр:
php codecept.phar bootstrap ~/projects/drupal/
В сущности, опция -c
позволяет указать не только путь, но и файл конфигурации. Таким образом у вас может быть несколько различных файлов codeception.yml
в одном тестовом наборе. Вы можете использовать их для указания разных переменных окружения и настроек. Просто передайте имя конфигурационного файла в параметре -c
для того, чтобы выполнить тесты с настройками, указанными в данном конфигурационном файле.
Есть несколько путей позволяющих выполнить группу тестов. Вы можете выполнить тесты в определенной директории:
php codecept.phar run tests/acceptance/admin
Или выполнить одну (или несколько) групп тестов:
php codecept.phar run -g admin -g editor
В данном случае будут выполнены все тесты принадлежащие группам admin или editor. Концепция групп взята из PHPUnit и его классических тестов, которые ведут себя подобным образом. Чтобы добавить Cept тест к группе, используйте переменную $scenario
:
<?php
$scenario->group('admin');
$scenario->group('editor');
// or
$scenario->group(array('admin', 'editor'))
// or
$scenario->groups(array('admin', 'editor'))
$I = new WebGuy($scenario);
$I->wantToTest('admin area');
?>
Чтобы добавить тест к группе классических или Cests тестов, можно использовать аннотацию @group
:
<?php
/**
* @group admin
*/
public function testAdminUser()
{
$this->assertEquals('admin', User::find(1)->role);
}
?>
Та же аннотация может быть использована в Cest классах.
В случае, если Вы хотите получить class-like структуру ваших Cept тестов, вместо использования простого PHP, Вы можете использовать Cest формат. Это очень просто и полностью совместимо с Cept сценариями. Если Вы считаете, что Ваши тесты стали достаточно длинными и Вы хотите разбить их на части, Вы можете поместить их внутрь класса.
Для генерации Cest файла, воспользуйтесь следующей командой:
php codecept.phar generate:cest suitename CestName
Это сгенерирует файл похожий на этот:
<?php
class BasicCest
{
public function _before()
{
}
public function _after()
{
}
// tests
public function tryToTest(\WebGuy $I) {
}
}
?>
Каждый публичный метод Cest класса (кроме начинающихся с _
) будет выполнен как тест, куда первым параметром будет передан Guy-класс
, а вторым параметром будет передана переменная $scenario
.
В методах _before
и _after
можно указывать разнообразные настройки, которые будут выполняться до и после тестов данного класса. Это делает Cest тесты более гибкими, чем Cepts тесты, которые основываются только на похожих методах в Helper классах.
Как Вы могли видеть выше, мы передаем класс Guy
в метод tryToTest
. Это позволяет писать сценарии тестирования точно так же, как мы делали это ранее.
<?php
class BasicCest
{
// test
public function checkLogin(\WebGuy $I) {
$I->wantTo('log in to site');
$I->amOnPage('/');
$I->click('Login');
$I->fillField('username', 'jon');
$I->fillField('password','coltrane');
$I->click('Enter');
$I->see('Hello, Jon');
$I->seeInCurrentUrl('/account');
}
}
?>
Стоит отметить, что при использовании Cest файлов появляются некоторые ограничения. Вы не сможете работать с _bootstrap.php
так как Вы делали это в Cept тестах. Иногда удобно хранить некоторые переменные, которые должны быть переданы тесту в bootstrap файлах.
В файлах Cest Вам придется включать все внешние переменные вручную, с помощью глобальных или статических переменных.
В качестве обходного пути можно использовать классы фикстур Fixtures, которые являются, по сути, глобальным хранилищем переменных. Можно передать любые данные из _bootstrap.php
или любого другого места с помощью вызова Fixtures::add()
. Вы можете использовать в классах Cest методы _before
и _after
для загрузки фикстур в начале теста и их удаления после его выполнения, что так же довольно удобно.
Как Вы могли заметить, классы Cest не имеют родителя, как, к примеру, \Codeception\TestCase\Test
или PHPUnit_Framework_TestCase
. Это сделано нарочно. Это позволяет Вам расширять данные классы путем создания общего класса родителя. В данном классе Вы можете описать общие поведения и методы, которые в дальнейшем могут быть использованы в унаследованных классах.
При этом не забудьте установить для таких методов модификатор
protected
, иначе они будут выполнены как тесты.
В дополнение, Вы можете определить метод _failed
в классах Cest, который будет вызван в случае, если в тесте произошла ошибка error
или он 'провалился'.
добавлено начиная с версии 1.7.0
Вы можете управлять Cest файлами с помощью аннотаций. Вы можете использовать аннотацию @guy
для передачи Guy-класса
отличного от того, что установлен в конфигурации. Это довольно удобно, если Вы хотите передать StepObject здесь (смотрите ниже).
<?php
/**
* @guy WebGuy\AdminSteps
*/
class AdminCest {
function banUser(WebGuy\AdminSteps $I)
{
// ...
}
}
?>
Аннотация может быть добавлена к методу в doc-блоке блоке.
Вы можете контролировать порядок выполнения используя аннотации @before
и @after
, а также переместить некоторые действия в protected (не тестируемые) методы и вызвать их до или после тестового метода, добавляя их в аннотации.
<?php
class ModeratorCest {
protected function login(WebGuy $I)
{
$I->amOnPage('/login');
$I->fillField('Username', 'miles');
$I->fillField('Password', 'davis');
$I->click('Login');
}
/**
* @before login
*/
function banUser(WebGuy $I)
{
$I->amOnPage('/users/charlie-parker');
$I->see('Ban', '.button');
$I->click('Ban');
}
}
?>
Вы так же можете использовать @before
и @after
для подключаемых функций. Однако, нельзя иметь несколько аннотаций в одном методе.
Во время роста базы тестов может потребоваться их рефакторинг, возможно, понадобится выделить некоторые общие поведения и методы. Классический пример — действие login
, которое возможно будет вызываться практически в каждом тесте из тестового набора. Мудрое решение — написать данное действие однажды и использовать его во всех тестах, где это необходимо.
Не забывайте принцип DRY :)
Вполне очевидно, что Вы можете использовать собственные классы для определения похожих методов.
<?php class TestCommons
{
public static $username = 'jon';
public static $password = 'coltrane';
public static logMeIn($I)
{
$I->amOnPage('/login');
$I->fillField('username', 'jon');
$I->fillField('password','coltrane');
$I->click('Enter');
}
}
?>
Этот файл затем может быть подключен в файл _bootstrap.php
<?php
// bootstrap
require_once '/path/to/test/commons/TestCommons.php';
?>
и затем может быть использован в Ваших сценариях:
<?php
$I = new WebGuy($scenario);
TestCommons::logMeIn($I);
?>
Теперь идея должна быть Вам понятна. Codeception не обеспечивает единой стратегии при управлении тестами. Однако он достаточно гибок и позволяет создавать любые необходимые классы, которые могут понадобиться Вам во время тестирования. Используя похожий подход, Вы можете реализовать паттерны PageObject
и StepObject
.
В следующих версиях Codeception будет использовать PageObjects и StepObjects из коробки. Однако сейчас Вы можете попробовать реализовать ваши собственные версии данных объектов. У нас есть пара отличных статей на данную тему, обратившись к которым Вы сможете разобраться в том, что же такое PageObjects, почему Вам может быть полезно их использовать и как они могут быть реализованы.
- Управления стаями (тестов) by Michael Bodnarchuk.
- Реализация Page Objects в Codeception by Jon Phipps.
Codeception — фреймворк, который на первый взгляд выглядит довольно просто. Однако он позволяет создавать достаточно мощные тесты, имеющие единый API, рефакторить их и писать тесты быстрее используя интерактивную консоль. Тесты Codeception легко могут быть организованны в группы или в классы Cest
. Вероятно, это достаточно большой функционал для одного фреймворка. Не смотря на это, Codeception следует принципу KISS: его просто изучить, просто использовать, просто расширять.