Могу ли я заставить 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 и пересылка теперь имеют настройку для этого в разделе "Тестирование" > "Параметры тестирования" > "Продолжить запуск тестового исполнения". При снятии этой опции запускается новый движок, каждый из которых запускается.