Могу ли я заставить MSTest использовать новый процесс для каждого тестового прогона?
Мы используем тест-тестировщик VS 2010 (MSTest) для автоматического функционального тестирования. Когда мы запускаем тесты из Visual Studio, VS создает процесс под названием QTAgent32.exe, и он запускает тесты в этом процессе.
Мы обнаружили, что, когда мы выполняем несколько тестовых прогонов, MSTest повторно использует один и тот же процесс QTAgent32 - идентификатор процесса не изменяется. Это проблема для нас, поскольку код, который мы тестируем, - это P/Invoking для неуправляемой библиотеки DLL. DLL необходимо инициализировать только один раз в течение всего жизненного цикла процесса. У нас есть метод [AssemblyInitialize], но он выполняется один раз для каждого тестового прогона. Если мы выполним несколько тестовых прогонов, он будет выполняться несколько раз в том же процессе.
Каждый раз, когда мы выполняем тестовый прогон, MSTest создает новый appdomain; но все эти приложения находятся в одном процессе.
Итак, мне интересно: есть ли способ показать тестировщику Visual Studio использовать новый процесс каждый раз, когда мы запускаем тесты? Я просмотрел конфигурацию ".testsettings", но ничего не увидел.
Ответы
Ответ 1
Не знаю, как далеко вы хотите пойти с ним, но одним из решений может быть создание вашего хоста unit test
http://technet.microsoft.com/fr-fr/query/bb166558
эта ссылка показывает, как создавать адаптеры, также вы можете запустить новый процесс для evertest, создать связную связь и разорвать ее после теста.
Я знаю, что MS сама использует другой хост для запуска тестов под ролями
http://research.microsoft.com/en-us/projects/pex/molestutorial.pdf
Ответ 2
Я смог получить эту работу после чтения комментария Wiktor о FreeLibrary().
Я использовал этот класс, созданный Майком Стойлом, который предоставляет обертки вокруг LoadLibrary, GetProcAddress и FreeLibrary. Таким образом, я могу загрузить библиотеку один раз в каждом тестовом прогоне, вызвать необходимые методы, а затем освободить библиотеку в конце тестового прогона.
В коде Mike Stall используется Marshal.GetDelegateForFunctionPointer, который преобразует неуправляемый указатель на управляемый тип делегата.
Мне пришлось заменить декларации extern [DllImport] декларациями для типов делегатов. Поэтому я преобразовал это:
[DllImport("asesignal.dll")]
public static extern bool ASESDK_Initialize(string licenseCode);
:
public delegate bool ASESDK_Initialize(string licenseCode);
Код Майка Столла содержал примеры с общими делегатами (Action <T> и т.д.). Но я не мог заставить это работать, поэтому создал собственные типы делегатов.
Я могу динамически загружать DLL следующим образом:
_ht = new UnmanagedLibrary(@"c:\windows\system32\asesignal.dll");
Чтобы вызвать функцию, я делаю это:
var function = _ht.GetUnmanagedFunction<ASESDK_Initialize>("ASESDK_Initialize");
function(licenseCode);
Спасибо Wiktor и np-hard за вашу помощь!
Ответ 3
VS 2013 и пересылка теперь имеют настройку для этого в разделе "Тестирование" > "Параметры тестирования" > "Продолжить запуск тестового исполнения". При снятии этой опции запускается новый движок, каждый из которых запускается.