Как ускорить тестирование сущности в symfony 4

Статья о модульном тестировании сущности в symfony 4 относительно валидации.

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

Как ускорить тестирование?

В документации symfony по этому поводу написано:

Don’t test the validation: it is applied by a listener that is not active in the test case and it relies on validation configuration. Instead, unit test your custom constraints directly.

(http://symfony.com/doc/current/form/unit_testing.html)

Поэтому тестирование можно упростить: загрузить валидатор для сущности, скормить ему объект с валидными (или невалидными) данными и проверить результат. Никакой авторизации, фикстур, заполнения форм и других телодвижений.
Допустим, у нас есть сущность MyEntity с полями name, description и ограничениями на name: не null, minLenght, maxLenght. Проверить, установлены ли нужные ограничения (с использованием phpunit) можно так:

<?php

namespace App\Tests\Controller\Admin;

use App\Entity\MyEntity;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Validation;

class MyEntityValidationTest extends TestCase
{
    /**
     * @dataProvider getMyEntityInvalidData
     */
    public function testMyEntityIsInvalid($name, $description)
    {
        // enableAnnotationMapping для ограничений в аннотациях
        $validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator(); 
        // если ограничения например в yaml, то надо так:
        /*
        $validator = Validation::createValidatorBuilder()->addYamlMapping('/your/path/to/validitor/validation.yaml')->getValidator(); 
        */

        $quest = new MyEntity();
        $quest->setName($name);
        $quest->setDescription($description);
        /** @var ConstraintViolation[] $violations */
        $violations = $validator->validate($quest);

        $this->assertTrue(count($violations) = 1);
    }
    public function getMyEntityInvalidData()
    {
        // null name
        yield ['name' => null, 'description' => 'valid description'];
        // invalid name length
        yield ['name' => '1', 'description' => 'valid description'];
        //invalid name length
        yield [
            'name' => 'qwjdhfnvjcnfhvn nvhf chfn ndnwb nvbchf r nfnefhvn nvjdhf2',
            'description' => 'valid description',
        ];
    }

Может возникнуть проблема со сложными ограничениями, например на уникальность. Если у вас доктрина, то во время выполнения теста возникнет ошибка

doctrine.orm.validator.unique’ not found

так как никакая orm в этот тесте не существует.
Это проблему можно решить так: разделить простые и сложные валидации по разным источникам(одни в аннотациях, другие в yaml), и в модульных тестах загружать и проверять только простые. Костыль, но для достижения цели (ускорения) работает.
А сложные ограничения, с базой данных, проверять уже в функциональных. Выигрыш во времени будет. Наверное, можно сделать заглушку для валидатора, но это уже другая история.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code