phpunit - тестирование проходит мучительно медленно


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

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

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

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

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

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

Приветствуется любая информация/комментарий оцененный.

Author: hakre, 2011-05-29

3 answers

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

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

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

Скорость

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

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

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

 30
Author: cweiske, 2016-04-14 09:47:32

Одна из вещей, которую я обычно делаю, когда тестирую с MySQL вместо :memory: SQLite, - это добавляю Hash::setRounds(5); внутри tests/CreatesApplication.php такой признак. Я испытал, что это сделает тесты, особенно с 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
Author: Hassan Azimi, 2017-11-01 18:29:40

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

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

    Phpunit --фильтр 'default_my_test'

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

    Phpunit--покрытие-html./отчет reporttest

 2
Author: Orod Semsarzadeh, 2017-11-15 01:05:31