Основы тестирования
Автоматический тест — код, который проверяет другой код: открывает страницу, вызывает функцию и сравнивает результат с ожидаемым. Набор тестов запускают одной командой после каждого изменения и сразу видят, не сломалось ли что-то. В проекте CodeIgniter уже настроен PHPUnit — программа для запуска тестов, — а сами тесты лежат в папке tests.
Первый тест
Создайте вручную файл tests/unit/BlogHelperTest.php. Он проверяет функцию reading_time() из урока о помощниках:
// tests/unit/BlogHelperTest.php
use CodeIgniter\Test\CIUnitTestCase;
class BlogHelperTest extends CIUnitTestCase
{
public function testShortTextTakesOneMinute(): void
{
helper('blog');
$this->assertSame('1 мин. чтения', reading_time('Короткий текст'));
}
}Имя файла и класса заканчивается на Test, имя метода начинается с test. assertSame() сравнивает ожидаемое значение с полученным.
Запуск
vendor/bin/phpunitВ Windows команда пишется как vendor\bin\phpunit. Терминал напечатает точку за каждый пройденный тест и итог: OK (1 test, 1 assertion). Если проверка не прошла, появятся ожидаемое и полученное значения и строка теста.
Тест страницы
Трейт FeatureTestTrait позволяет «открыть» адрес сайта без браузера:
// tests/feature/HomeTest.php
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\FeatureTestTrait;
class HomeTest extends CIUnitTestCase
{
use FeatureTestTrait;
public function testLoginPageOpens(): void
{
$result = $this->get('login');
$result->assertStatus(200);
$result->assertSee('Войти');
}
}Метод get() выполняет запрос к маршруту и возвращает ответ. Тест проверяет, что страница входа открывается с кодом 200 и содержит слово «Войти».
| Проверка | Что утверждает |
|---|---|
assertStatus(200) | Код состояния ответа |
assertSee('текст') | Текст есть на странице |
assertDontSee('текст') | Текста нет на странице |
assertRedirect() | Ответ — перенаправление |
assertSessionHas('user_id') | В сессии есть значение |
Тест с базой данных
Тесты работают с отдельной базой — подключением tests из app/Config/Database.php, чтобы не трогать рабочие данные. Трейт DatabaseTestTrait перед тестами выполняет миграции:
// tests/database/PostModelTest.php
use App\Models\PostModel;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
class PostModelTest extends CIUnitTestCase
{
use DatabaseTestTrait;
protected $migrate = true;
protected $refresh = true;
protected $namespace = 'App';
public function testInsertSavesPost(): void
{
model(PostModel::class)->insert(['title' => 'Тестовая статья', 'body' => 'Текст']);
$this->seeInDatabase('posts', ['title' => 'Тестовая статья']);
}
}$namespace = 'App' указывает, что миграции нужно брать из папки app. seeInDatabase() проверяет, что в таблице есть строка с такими значениями. По умолчанию тестовая база — SQLite в памяти, для неё нужно расширение PHP sqlite3.
Что проверять
Начните с того, что дороже всего сломать: вход на сайт, сохранение статьи, закрытые страницы. Хороший тест проверяет одно утверждение и не зависит от других тестов.
Частая ошибка
Тесты с базой нельзя направлять на рабочее подключение: свойство $refresh перед каждым тестом откатывает миграции и удаляет таблицы. Не меняйте группу tests в app/Config/Database.php на данные основной базы. Если нужен MySQL, создайте для тестов отдельную пустую базу, например blog_test.