Чтобы ответить на вторую часть вашего вопроса: есть ли что-то более глубокое, что препятствует распределению (хотя бы некоторых) тестов по нескольким потокам?
Большая часть кода работает только при однопоточном запуске. Случайно возникает конфликт ресурсов и взаимоблокировки при написании программ в предположении, что они будут выполняться однопоточными. И это прекрасно работает, потому что большинство программ на самом деле работают однопоточными. Параллелизм достигается за счет одновременного запуска нескольких копий или разных программ (одним из распространенных примеров являются веб-сценарии - большое количество пользователей, получающих доступ к одной странице, означает, что одновременно выполняется множество копий сценариев для этой страницы).
Представьте себе простой класс «log to file». Когда вы создаете экземпляр, он открывает файл для записи, а когда вы освобождаете экземпляр, он закрывает файл. Итак, первый тест создает экземпляр и запускает тест. Второй тест делает то же самое во втором потоке. И терпит неудачу, потому что второй экземпляр не может получить доступ для записи в файл. Но если запустить по одному, все тесты пройдут.
Все это может быть закодировано, и простой пример может быть настроен на работу. Но делать это, вероятно, не нужно для оригинальной программы . Необходимость написания поточно-ориентированного кода только для того, чтобы вы могли запускать модульные тесты, для многих нецелесообразна. Так что многопоточные юнит-тесты должны оставаться опциональным дополнением.