phpunit - тестирование мучительно медленное - PullRequest
42 голосов
/ 29 мая 2011

Я погружаюсь все глубже и глубже в мир юнит-тестирования.

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

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

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

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

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

Любое понимание приветствуется / комментарий приветствуется.

Ответы [ 3 ]

33 голосов
/ 29 мая 2011

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

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

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

Скорость

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

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

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

4 голосов
/ 01 ноября 2017

Одна из вещей, которые я обычно делаю, когда я тестирую с MySQL вместо :memory: SQLite, - это добавление 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;
}
2 голосов
/ 06 июля 2011

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

  1. фильтрация тестовых случаев. Например, если вы хотите проверить файл onw, просто нужно

    phpunit --filter 'Default_My_Test'

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

    phpunit --coverage-html ./report reportTest

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...