Подтвердить что ты не робот

Phpunit - тестирование болезненно медленное

Я погружаюсь глубже и глубже в мир модульных испытаний.

Одна из проблем, с которой я столкнулся, и это то, где я бы хотел получить обратную связь, - это когда вы запускаете несколько тестовых наборов, возможно, это только я, но мне нужно использовать параметр -process-isolation для моих тестов. Я могу запускать любой из своих наборов индивидуально без проблем, но выполнение 6-7 наборов, которые у меня есть до сих пор, с 180 утверждениями, которые распространяются между ними, терпит неудачу, если я запускаю без изоляции процесса. Проблема заключается в том, что использование этого параметра делает тестовый прогон длительностью 35 минут против обычных 2,5 минут. Это ожидание ожидания.

Проблема связана с использованием израсходованных контейнеров DI для конкретных тестов и контейнеров, которые неправильно переинициализируются при запуске наборов тестов. Статические свойства, установленные для DI-Container для проверки ожидаемых отказов, делают тесты в следующем пакете неудачными. Контейнер имеет параметр, который может содержать содержащийся объект в статическом var, чтобы возвращать один и тот же экземпляр при каждом вызове. Одиночный сингл. И это отлично работает на уровне приложений, это просто неприятность для тестирования.

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

Возможно, я делаю что-то неправильно (я надеюсь, что так!), но у меня сложилось впечатление, что если вы хотите запускать тесты с SUT в чистом состоянии для каждого теста, не обойтись без использования --process-изоляции. Это делает тестирование очень трудоемким и немного отвлекает от него радость. Я несколько обошел проблему, выполняя отдельные классы и тесты, когда я кодирую, и запускаю пакет в фоновом режиме до крупных коммитов.

Это то, что я испытываю в обычном режиме, и есть ли способ противостоять этому? Как вы, тестирующие, убедитесь, что время тестирования разумно? Как обрабатывается статика, чтобы не влиять на тестирование?

Любое понимание, оцененное/комментарий, оценено.

4b9b3361

Ответ 1

У вас есть несколько проблем.

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

Вторая проблема, которая приводит к вашей первой проблеме, заключается в том, что ваш код не поддается тестированию, потому что статические vars хранятся во время тестов - моя самая ненавистная проблема синглтона. Вы можете решить эту проблему, предоставив метод "очистка" или "reset" в контейнерах зависимостей. Они будут вызваны из метода setUp() в вашем классе основного теста и reset все в чистое состояние.

Speed ​​

Что касается времени выполнения тестов - я недавно написал запись о том, какие тесты были слишком медленными. Как правило, тесты слишком медленные, если вы не можете запускать их после сохранения файла или каждой фиксации в своем собственном окне. 10 секунд едва ли приемлемы для меня. Чем больше у вас тестов, тем медленнее будет их выполнение.

Если у вас действительно есть 35 минут, разделите свои тесты на разумные группы, чтобы вы могли запускать необходимые на своей машине - только те тесты, которые проверяли код, который вы изменили. Pyrus, установщик PEAR следующего поколения, обладает отличной функцией автоматически обнаруживать и запускать тесты, которые необходимо запустить, в зависимости от того, какие файлы вы используете изменилось. PHPUnit этого не имеет, но вы можете эмулировать это вручную и phpunit --group ..:)

Всегда заботитесь о насмешливых веб-сервисах и базах данных или, по крайней мере, запуская базу данных с необходимыми данными только для каждого отдельного теста. Ожидание 3 секунд для ответа веб-служб в тесте, подтверждающем, что вы можете сохранить пользователя в базе данных, - это то, чего вы никогда не хотите.

Ответ 2

Несколько трюков;

  • фильтрация ваших тестовых примеров, например, если вы хотите протестировать onw файл, просто нужно

    phpunit --filter 'Default_My_Test'

  • Удаление покрытия кода в файле phpunit.xml. Если вы хотите получить покрытие кода, выполните следующие действия:

    phpunit --coverage-html./report reportTest

Ответ 3

Одна из вещей, которые я обычно делаю, когда я тестирую MySQL вместо SQLite :memory:, я добавляю Hash::setRounds(5); внутри tests/CreatesApplication.php Trait, как это. Я испытал это, чтобы сделать тесты особенно с MySQL намного быстрее:

public function createApplication()
{
    $app = require __DIR__ . '/../bootstrap/app.php';

    $app->make(Kernel::class)->bootstrap();

    // TODO: DON'T FORGET TO IMPORT HASH OBJECT ON TOP
    Hash::setRounds(5);

    return $app;
}