9

Поскольку время, необходимое для запуска полного набора PHPUnit, наша команда начинает задаваться вопросом, есть ли возможность параллельно выполнять параллельные тесты. Недавно я прочитал статью о Paraunit, также написал Sebastian Bergman, он добавит параллелизм в PHPUnit 3.7.Параллельное тестирование PHPUnit в тестах интеграции

Но остается проблема с интеграционными тестами или, в более общем плане, тестами, которые взаимодействуют с БД. Для обеспечения согласованности, testDB должен быть сброшен, а приборы будут загружены после каждого теста. Но в параллельных тестах есть проблема с условиями гонки, потому что все процессы используют тот же DB.

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

В моей команде мы используем MongoDB, поэтому одним из решений было бы программное создание конфигурационного файла для каждого процесса PHPUnit с сгенерированным именем БД (для этого процесса) и в методе setUp() мы могли бы клонировать основной TestDb в этот временный. Но прежде чем мы начнем применять этот подход, я хотел бы попросить ваши идеи по этой теме.

+1

Смежный вопрос (о параллельном XUnit в целом): http://programmers.stackexchange.com/q/56092/58909 Но опять же, как к испытаний с базы данных на самом деле не решаются. –

+0

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

+0

Я бы запускал их в отдельных виртуальных машинах. –

ответ

4

Это хороший вопрос: подготовка к параллельным блочным испытаниям потребует изучения некоторых новых лучших практик, и я подозреваю, что некоторые из них будут замедлять наши тесты.

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

При использовании PDO я обычно использую sqlite :: memory: каждый тест получает свою собственную базу данных. Это анонимно и автоматически очищается, когда тест заканчивается. (Но я заметил некоторые проблемы с этим, когда вы в реальном приложении не используете sqlite: Suggestions to avoid DB deps when using an in-memory sqlite DB to speed up unit tests)

При использовании базы данных, которая не имеет выбор в памяти, создайте базу данных со случайным именем. Если распараллеливание на уровне процесса PHPUnit, довольно грубое, вы можете использовать процесс pid. Но это не имеет реальных преимуществ перед случайным именем. (Я знаю, что PHP однопоточный, но, возможно, в будущем у нас будет собственный модуль phpUnit, который будет использовать потоки для параллельного тестирования тестов, мы также можем быть готовы к этому.)

Если у вас есть xUnit Test Книга шаблонов, глава 13 посвящена тестированию баз данных (относительно короткая). Также полезны главы 8 и 9 по временным и постоянным приборам. И, конечно же, большая часть книги на абстракцию слоях, чтобы сделать насмешливую проще :-)

+0

Спасибо за ответ. В наших модульных тестах мы используем mocks, и они действительно быстрые!Но теперь мы создаем тесты для нашего REST-интерфейса и хотели бы протестировать его в целом с помощью функциональных тестов, и они медленны. Я попробовал инструмент [paratest] (https://github.com/brianium/paratest) с переменной среды TEST_TOKEN, используемой для создания временной базы данных для каждого процесса phpunit. Но все же есть некоторые условия гонки из-за ZF2/Doctrine/caching, и действительно сложно найти проблему. Поэтому мы решили дождаться параллельной реализации phpunit от Себастьяна Бергмана. –

0

Но остается проблема с интеграционными тестами, или, более в целом, тесты, которые взаимодействуют с БД. Для обеспечения согласованности, testDB необходимо сбросить и после каждого теста загрузить весы. Но в параллельных тестах есть проблема с условиями гонки, потому что все процессы используют одну и ту же БД.

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

Вы можете избежать конфликтов интеграционного теста 2 способа:

  • работающих только те тесты параллельно, который использует очень разные таблицы баз данных, так что они не противоречат
  • создать новую базу данных для противоречивые испытания

Оф. вы можете объединить эти 2 решения. Я не знаю ни одного phpunit test runner, который поддерживает любой из этих подходов, поэтому я думаю, что вам нужно написать собственный тестовый бегун, чтобы ускорить процесс ... Кстати, вы все же можете группировать свои интеграционные тесты и запускать только несколько из них сразу, если вы используете их по разработке ...

Помните, что те же конфликты могут вызывать проблемы параллелизма при большой загрузке в PHP. Например, если вы заблокируете 2 файла в обратном порядке под 2 отдельными действиями контроллера, ваше приложение может оказаться в тупике ... Я ищу способ протестировать проблемы параллелизма в PHP, но пока не повезло. У меня нет времени на то, чтобы написать собственное решение, и я не уверен, что смогу это сделать, это довольно сложно ...: S

0

Существует также эта удивительная библиотека (fastest) для параллельной работы тестов , Он оптимизирован для функциональных/интеграционных тестов, обеспечивая простой способ работы с базами данных N параллельно.

Наша старая кодовая база работает через 30 минут, теперь через 7 минут с 4-мя процессорами.

Особенности
  • Функциональные тесты могут использовать базу данных на процессор, используя переменную среды.
  • Тесты рандомизированы по умолчанию.
  • Не связан с PhpUnit, вы можете выполнить любую команду.
  • Разработан на PHP без зависимостей.
  • В качестве входных данных вы можете использовать файл phpunit.xml.dist или использовать канал.
  • Включает расширение Behat, которое позволяет легко транслировать сценарии.
  • Увеличьте многословие с опцией -v.

Использование

find tests/ -name "*Test.php" | ./bin/fastest "bin/phpunit -c app {};"

Смежные вопросы