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

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

В качестве базы для запуска тестов, Codeception использует PHPUnit. Таким образом, любой PHPUnit тест может быть добавлен к набору тестов (test suite) Codeception, после чего может быть успешно выполнен.
Если Вы уже писали тесты для PHPUnit, в Codeception Вы можете использовать их без изменений. Codeception добавляет некоторые функции или помощники (helpers), которые позволяют упростить часть задач.
В случае, если у Вас отсутствует опыт написания тестов, рекомендуем для начала ознакомится с [Документацией по PHPUnit](http://www.phpunit.de/documentation.html).
В данном разделе отсутствует описание основ модульного тестирования, вместо этого здесь описаны особенности и функции, которыми Codeception дополняет модульные тесты.

>__Повторим: Нет необходимости в установке PHPUnit для запуска его тестов. Codeception может выполнять их.__

## Создание тестов

Codeception имеет набор простых генераторов для того, чтобы упростить создание тестов.
Для начала Вы можете создать классический PHPUnit тест унаследованный от класса `\PHPUnit_Framework_TestCase`.
Это можно сделать при помощи следующей команды:

```bash
$ php codecept.phar generate:phpunit unit Example
```

Codeception имеет собственные дополнения к стандартным модульным тестам. Давайте попробуем создать их.
Для создания модульных тестов дополненных Codeception используется другая команда:

```bash
$ php codecept.phar generate:test unit Example
```

Обе команды создадут новый файл `ExampleTest`, расположенный в каталоге `tests/unit`.

Тест созданный командой `generate:test` будет выглядеть так:

```php
<?php
use Codeception\Util\Stub;

class ExampleTest extends \Codeception\TestCase\Test
{
   /**
    * @var CodeGuy
    */
    protected $codeGuy;

    // executed before each test
    protected function _before()
    {
    }

    // executed after each test
    protected function _after()
    {
    }
}
?>
```
Этот класс имеет два предопределенных метода в начале: `_before` и `_after`. Вы можете использовать их для создания объектов перед началом выполнения тестов и их удаления после того, как тест будет выполнен.

Как Вы могли заметить, PHPUnit методы setUp/tearDown заменены на методы: `_before`, `_after`.
Настоящие методы setUp и tearDown реализованы внутри родительского класса `\Codeception\TestCase\Test` и используются для подключения файла загрузчика (bootstrap) (по умолчанию, `_bootstrap.php`), а так же для настройки класса `CodeGuy`, что позволяет использовать все возможности Cept-файлов внутри модульных тестов. Точно так же, как и в других видах тестов, Вы можете настроить модули специфичные для класса `CodeGuy` в конфигурационном файле `unit.suite.yml`.
Таким образом, если Вы реализуете методы `setUp` и `tearDown`, не забудьте вызвать их родительские методы внутри своих.


```yaml
# Codeception Test Suite Configuration

# suite for unit (internal) tests.
class_name: CodeGuy
modules:
    enabled: [Unit, CodeHelper]
```

### Тестирование баз данных

Вероятно, нет особо полезных модулей, которые должны быть установлены для класса `CodeGuy` по умолчанию. Все потому, что класс `CodeGuy`, по большей части, используется для scenario-driven модульных тестов, описанных в следующих разделах. Однако, в этом нет ничего страшного, мы легко можем добавить необходимые модули. К примеру, мы можем добавить модуль Db для тестирования данных в БД.

```yaml
# Codeception Test Suite Configuration

# suite for unit (internal) tests.
class_name: CodeGuy
modules:
    enabled: [Unit, Db, CodeHelper]
```

После выполнения комманды "сборки":

```bash
$ php codecept.phar build
```

Новые методы будут добавлены в класс `CodeGuy`. Таким образом, теперь Вы можете использовать в Ваших тестах методы для работы с БД:

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

База данных будет очищена и заполнена после прохождения каждого теста, точно так же как это происходит в функциональных и приемочных тестах.

>Если такое поведения модуля `Db` Вам не подходит для текущего набора тестов, просто смените его настройки.

### Модули

*добавлено в 1.5.2*

Codeception позволяет получить доступ к свойствам и методам любого из модулей, определенных для данного набора. Вместо использования класса `CodeGuy`, использование прямого доступа к модулям позволяет получить доступ к любым публичным свойствам конкретного модуля.

К примеру, если Вы используете модуль `Symfony2`, обратится к Symfony контейнеру можно следующим способом:

```php
<?php
/**
 * @var Symfony\Component\DependencyInjection\Container
 */
$container = $this->getModule('Symfony2')->container;
?>
```

>Все публичные свойства модулей описаны в соответствующих разделах справки.

### Начальная загрузка (Bootstrap)

Файл загрузки (bootstrap) расположен в директории набора тестов и имеет название `_bootstrap`. Данный файл **подключается перед выполнением каждого теста** (с помощью метода `setUp` родительского класса). Он широко используется в приемочных (acceptance) и функциональных (functional) тестах для инициализации различных предустановленных переменных. В модульных тестах он может быть полезен при использовании одинаковых данных с разными тестами. Однако его главное предназначение -— установка автозагрузчика для Вашего проекта внутри данного класса. Иначе Codeception не сможет найти тестируемые классы и тесты не выполнятся.

### Заглушки (Stubs)

В первой строке класса подключается класс Strub для использования заглушек в тестах. Заглушки (strubs) позволяют Вам легко подменять реальные классы их муляжами.
Не тратьте ваше время на указание большого количетва параметров в конструкторе просто вызовите `Stub::make` для содания класса заглушки.

>Заглушки (Stubs) созданы на базе PHPUnit's mocking framework. Изучите [PHPUnit Manual](http://www.phpunit.de/manual/current/en/test-doubles.html), если Вы нуждаетесь в дополнительной информации на тему заглушек (stubs or mocks).

Полное описание класса для работы с заглушками (stub util class) находится [здесь](http://www.codeception.com/docs/reference/Stubs).

### Соединим полученные знания вместе!

Меньше слов, больше кода для лучшего усвоения материала:

```php
<?php
use Codeception\Util\Stub;
class ExampleTest extends \Codeception\TestCase\Test
{
    protected $codeGuy;

    public function _before()
    {

        $this->user = new User();

    }

    public function testUserCanBeBanned()
    {
    	$this->user->setIsBanned(true);
    	$this->user->setUpdatedBy(Stub::make('User', array('name' => 'admin')));
    	$this->user->save();
    	$this->codeGuy->seeInDatabase('users', array('name' => 'Miles', 'is_banned' => true));
    }
}
?>
```

## Заключение

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

Трудились и переводили ребята из [amyLabs](http://amylabs.ru/)
