Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Тестирование

Тест — код, который сам открывает страницу приложения и проверяет ответ: код состояния, сработавший маршрут, текст в HTML. Запустив тесты после изменения, вы сразу видите, не сломалось ли что-то в другом месте. Laminas использует для этого PHPUnit и пакет laminas-test.

Установка

composer require --dev laminas/laminas-test

Ключ --dev означает, что пакет нужен только при разработке. В заготовке уже есть файл настроек phpunit.xml.dist и пример теста в module/Application/test.

Где лежат тесты

Тесты модуля кладут в module/<Модуль>/test. Сообщите об этой папке в двух местах. В composer.json — раздел autoload-dev:

{
    "autoload-dev": {
        "psr-4": {
            "ApplicationTest\\": "module/Application/test/",
            "BlogTest\\": "module/Blog/test/"
        }
    }
}

В phpunit.xml.dist — ещё одна папка в наборе тестов:

<testsuites>
    <testsuite name="Application Test Suite">
        <directory>./module/Application/test</directory>
        <directory>./module/Blog/test</directory>
    </testsuite>
</testsuites>

После этого выполните composer dump-autoload.

Первый тест

Создайте файл вручную:

// module/Blog/test/Controller/PostControllerTest.php
namespace BlogTest\Controller;
 
use Blog\Controller\PostController;
use Laminas\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
 
class PostControllerTest extends AbstractHttpControllerTestCase
{
    protected function setUp(): void
    {
        $this->setApplicationConfig(
            include __DIR__ . '/../../../../config/application.config.php'
        );
 
        parent::setUp();
    }
 
    public function testLoginPageOpens(): void
    {
        $this->dispatch('/login', 'GET');
 
        $this->assertResponseStatusCode(200);
        $this->assertControllerName(AuthController::class);
        $this->assertMatchedRouteName('login');
    }
}

Метод setUp() выполняется перед каждым тестом и загружает настройки приложения. dispatch() отправляет запрос внутри PHP, без веб-сервера, а методы assert... проверяют результат.

Запуск

vendor/bin/phpunit

PHPUnit напечатает точку за каждый пройденный тест и строку OK в конце. Если страница вернёт другой код, появится сообщение о том, какой тест не прошёл и что ожидалось.

Подмена сервисов

Тесту не нужна настоящая база. Сервис в контейнере заменяют заглушкой — объектом, который возвращает заранее заданные данные:

use Blog\Model\Post;
use Blog\Model\PostTable;
 
public function testViewShowsPost(): void
{
    $post = new Post();
    $post->exchangeArray(['id' => 1, 'title' => 'Первая статья', 'body' => 'Текст']);
 
    $table = $this->createMock(PostTable::class);
    $table->method('find')->willReturn($post);
 
    $services = $this->getApplicationServiceLocator();
    $services->setAllowOverride(true);
    $services->setService(PostTable::class, $table);
 
    $this->dispatch('/blog/1');
 
    $this->assertResponseStatusCode(200);
    $this->assertStringContainsString('Первая статья', $this->getResponse()->getContent());
}

setAllowOverride(true) разрешает заменить уже описанный сервис. Контроллер получит заглушку вместо PostTable, и запрос к базе не выполнится.

Частые проверки

МетодЧто проверяет
assertResponseStatusCode(200)Код ответа
assertMatchedRouteName('blog')Сработавший маршрут
assertControllerName($class)Контроллер из маршрута
assertActionName('index')Действие
assertRedirectTo('/blog')Перенаправление на адрес

Отправку формы проверяют третьим аргументом dispatch(): $this->dispatch('/blog/add', 'POST', ['title' => 'Тест']).

Частая ошибка

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

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.