В соответствии с наблюдаемым поведением, средство выполнения тестов Visual Studio (VSTest) выполняет несколько сборок теста параллельно. Он запускает несколько процессов (не более одного на ядро процессора). Каждый такой процесс содержит свою собственную копию CLR, каждый из которых загружает некоторый AppDomain и, конечно, отдельный экземпляр тестовой сборки.
Все это означает, что статические члены не являются общими, а также что синхронизация не работает для нескольких экземпляров CLR из-за SemaphoreSlim
, который опирается на примитивы синхронизации CLR.
Я могу придумать два возможных решения:
Решение 1: синхронизация между процессами
Заменить СемафорSlim на Семафор . Последний может быть инициализирован как семафор с именем компьютера, что позволяет нескольким процессам синхронизироваться по одному и тому же экземпляру семафора, идентифицированному по имени строки. См. пример здесь . См. Также Semaphore и SemaphoreSlim для получения дополнительной информации.
Если только некоторые из ваших тестов требуют синхронизации, это может быть хорошим решением. Однако, если большинство или все тесты должны быть синхронизированы, нет смысла запускать параллельные тестовые процессы - см. Решение №2.
Решение 2: отключить параллельные процессы тестирования
Вы можете контролировать количество параллельных процессов через элемент <MaxCpuCount>
в файле .runsettings
. Установка его значения в 1 должна отключить параллельные процессы:
<RunSettings>
<RunConfiguration>
<MaxCpuCount>1</MaxCpuCount>
</RunConfiguration>
</RunSettings>
Подробнее см. Настройка модульных тестов с использованием файла .runsettings .
Это не значит, что вы не можете распараллелить свои тесты. MSTest имеет функцию под названием «Выполнение параллельного теста в сборке» (IAP), которую можно включить, включив следующий атрибут уровня сборки (обычно в AssemblyInfo.cs ):
[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]
В отличие от бегуна VSTest, который порождает процессы, IAP порождает несколько потоков, все из которых используют один и тот же домен приложения. В этом случае есть только одна копия статических членов, и синхронизация на основе CLR с SemaphoreSlim
также работает.
Подробнее о IAP в этом сообщении: MSTest V2: выполнение параллельного теста в сборке