Почему платформы xUnit не позволяют тестам работать параллельно?

15

Знаете ли вы о какой-либо инфраструктуре xUnit, которая позволяет параллельно выполнять тесты, чтобы использовать несколько ядер на современном компьютере?

Если никто (или так мало) из них не делает этого, может быть, есть причина ... Является ли тесты такими быстрыми, что люди просто не чувствуют необходимости их паралеллизировать?

Есть ли что-то более глубокое, что препятствует распределению (хотя бы некоторых) тестов по нескольким потокам?

Ксавье Ноде
источник
Модульное тестирование определенно медленное. Даже если бы каждый тест был бы быстрым, он накапливался, поскольку у людей буквально миллионы тестовых случаев.
Pacerier

Ответы:

6

NUnit 2.5 в комплекте pNUnit, который позволяет выполнять тесты параллельно.

Этот выпуск включает в себя pNUnit, расширенный NUnit Runner для распределенных параллельных тестов. Программа pNUnit была разработана в Codice Software для использования при тестировании Plastic SCM и внесена в NUnit. Для получения дополнительной информации об использовании pNUnit посетите сайт pNUnit.

Сторона JUnit имеет параллельный юнит, а также амино .

Аарон Макивер
источник
Таким образом, единственная причина для других структур будет «еще не реализована»?
Ксавье Нодет,
1
@ Ксавьер Да; это справедливое утверждение.
Аарон Макивер
10

Чтобы ответить на вторую часть вашего вопроса: есть ли что-то более глубокое, что препятствует распределению (хотя бы некоторых) тестов по нескольким потокам?

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

Представьте себе простой класс «log to file». Когда вы создаете экземпляр, он открывает файл для записи, а когда вы освобождаете экземпляр, он закрывает файл. Итак, первый тест создает экземпляр и запускает тест. Второй тест делает то же самое во втором потоке. И терпит неудачу, потому что второй экземпляр не может получить доступ для записи в файл. Но если запустить по одному, все тесты пройдут.

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


источник
+1 Это должен быть исключенный ответ, потому что на самом деле он отвечает на вопрос «почему».
Оливер Вейлер
4

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

Клинт Миллер
источник
Это не для платформы тестирования (xUnit), чтобы заботиться; это деталь реализации.
Аарон Макивер
И не все тесты, написанные в рамках модульного тестирования, являются модульными тестами, точно так же, как тот, который обращается к базе данных, на самом деле не является модульным тестом, а скорее интеграционным тестом.
c_maker
То, что тест касается базы данных, не означает, что это интеграционный тест. Метод, который выполняется частично в C # и частично в sproc базы данных, например, все еще концептуально является модульным тестом, если не требуется предварительная конфигурация (т. Е. Присутствует схема данных, но нет данных). Такие тесты могут создавать данные для отдельного прогона, но по завершении должны быть сброшены в пустое состояние. Это, вероятно, противоречивое мнение, но такие тесты нельзя рассматривать как интеграционные тесты, потому что это явно тесты с нулевой конфигурацией, с нулевым развертыванием, которые тестируют небольшие блоки кода.
Триынко
2

Хотя JUnit сам по себе может этого не допустить (хотя я не очень хорошо знаком с его последними версиями), Maven с его плагином Surefire имеет возможность запускать тесты параллельно. Я еще не пробовал это все же.

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

Петер Тёрёк
источник
0

Многопоточное кодирование не тривиально. Даже когда это делают люди, которые знают, что они делают, могут возникать ошибки, зависящие от времени. Их сложно исправить. Разобравшись с одной из нескольких тысяч ошибок, связанных с многопоточностью, я бы предпочел не включать их в мою среду тестирования. Первое исправление, которое я получил, сработало, но при дальнейшем тестировании выяснилось, что оно только что стало ошибкой в ​​десятки тысяч.

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

Некоторые наборы тестов имеют зависимости между тестами, которые не нужно явно указывать при выполнении тестов в одном потоке. Однако на многопаровом двигателе они должны быть указаны явно. (Где должны существовать такие зависимости - это другой вопрос.)

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

BillThor
источник
0

MBUnit может выполнять тесты параллельно, просто указав некоторые атрибуты уровня сборки.

[assembly: DegreeOfParallelism(6)]
[assembly: Parallelizable(TestScope.All)]

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

xUnit 2.0 также должен поддерживать параллельное модульное тестирование, но я еще не пробовал.

Иво Грутджес
источник