Писать тесты — скучно? Только до первого бага в продакшене. С PHPUnit и Yii2 вы можете спать спокойно, зная, что ваш код проверен. В этой статье разберём, как настроить тесты в Yii2, писать их быстро и получать удовольствие.
Зачем вообще тестировать Yii2-приложение
Представьте: вы добавили новую фичу, всё работает. Но через неделю выясняется, что сломалась старая функция. Знакомо? Тесты — это ваша страховка. Они автоматически проверяют, что код делает то, что должен. В Yii2 есть встроенная поддержка PHPUnit, так что грех не пользоваться.
К тому же тесты помогают документировать код. Глядя на тест, сразу понятно, как должен вести себя метод. И рефакторить становится не страшно.
Установка и настройка PHPUnit в Yii2
Стандартный шаблон Yii2 (yii2-app-basic) уже включает PHPUnit в dev-зависимости. Если у вас advanced-шаблон, проверьте composer.json. Для установки достаточно выполнить:
composer require --dev phpunit/phpunit
Затем создайте папку tests в корне проекта. Внутри — структуру: unit, functional, acceptance. Для юнит-тестов (проверка отдельных классов) хватит unit.
Настройте автозагрузку. В composer.json добавьте:
"autoload-dev": {
"psr-4": {
"tests\\": "tests/"
}
}
И выполните composer dump-autoload. Теперь можно писать тесты.
Пишем первый юнит-тест
Юнит-тесты проверяют один класс или метод в изоляции. Допустим, у нас есть модель User с методом getFullName(). Создадим тест в tests/unit/models/UserTest.php:
<?php
namespace tests\unit\models;
use app\models\User;
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase
{
public function testGetFullName()
{
$user = new User();
$user->first_name = 'Иван';
$user->last_name = 'Петров';
$this->assertEquals('Иван Петров', $user->getFullName());
}
}
Запускаем: ./vendor/bin/phpunit tests/unit/models/UserTest.php. Если всё зелёное — отлично!
Функциональные тесты: проверяем контроллеры
Функциональные тесты эмулируют HTTP-запросы и проверяют ответы. В Yii2 для этого есть класс yii\codeception\fixtures и встроенный TestCase с поддержкой фикстур. Создадим тест для экшена actionIndex контроллера SiteController:
<?php
namespace tests\functional;
use app\controllers\SiteController;
use tests\functional\_base\FunctionalTester;
class SiteControllerTest extends \yii\codeception\TestCase
{
public function testIndex()
{
$this->assertTrue(true); // заглушка
}
}
На самом деле для функциональных тестов лучше использовать Codeception, который идёт в комплекте с Yii2. Но если хотите чистый PHPUnit, можно тестировать контроллеры через создание экземпляра и вызов экшенов напрямую.
Пример теста для метода контроллера:
public function testActionAbout()
{
$controller = new SiteController('site', Yii::$app);
$result = $controller->actionAbout();
$this->assertIsString($result);
}
Полезные лайфхаки и таблица параметров
Чтобы тесты были быстрыми и надёжными, используйте фикстуры — предустановленные данные. В Yii2 есть yii\test\Fixture. Также не забывайте про изоляцию: каждый тест должен работать независимо.
Вот таблица с основными методами PHPUnit, которые пригодятся:
| Метод | Что делает |
|---|---|
| assertEquals($expected, $actual) | Проверяет равенство значений |
| assertTrue($condition) | Утверждает, что условие истинно |
| assertInstanceOf($class, $object) | Проверяет, что объект принадлежит классу |
| expectException($exception) | Ожидает исключение |
/**
* @dataProvider additionProvider
*/
public function testAdd($a, $b, $expected)
{
$this->assertEquals($expected, $a + $b);
}
public function additionProvider()
{
return [
[0, 0, 0],
[1, 1, 2],
[2, 2, 4],
];
}
Что в итоге
Тесты в Yii2 с PHPUnit — это не страшно, а полезно. Начните с малого: напишите пару юнит-тестов для моделей. Постепенно добавите функциональные. Главное — регулярность. И помните: хороший тест — это тот, который ловит баг до того, как его увидит пользователь.
Удачи в тестировании! И пусть ваш код всегда будет зелёным.

