Как заставить MSTEST TestMethod сбросить все синглтоны / статики перед запуском?
-
08-07-2019 - |
Вопрос
Я использую MSTEST в Visual Studio 2008. Как можно, чтобы каждый метод модульного теста в определенном классе теста действовал так, как если бы это был первый тест для запуска, чтобы все глобальные состояния были сброшены перед выполнением каждого теста? Я не хочу явно очищать мир, используя TestInitialize, ClassInitialize, AssemblyInitialize и т. Д. Например:
[TestClass]
public class MyClassTests
{
[TestMethod]
public void Test1()
{
// The "Instance" property creates a new instance of "SomeSingleton"
// if it hasn't been created before.
var i1 = SomeSingleton.Instance;
...
}
[TestMethod]
public void Test2()
{
// When I select "Test1" and "Test2" to run, I'd like Test2
// to have a new AppDomain feel so that the static variable inside
// of "SomeSingleton" is reset (it was previously set in Test1) on
// the call to ".Instance"
var i2 = SomeSingleton.Instance;
// some code
}
Хотя похожий вопрос Появилась эта тема, только уточняется, что тесты не работают параллельно. Я понимаю, что тесты выполняются последовательно, но, похоже, нет способа явно принудительно назначить новый домен приложения для каждого метода (или что-то эквивалентное для очистки всех состояний).
В идеале я хотел бы указать это поведение только для небольшого подмножества моих модульных тестов, чтобы мне не приходилось платить штраф за создание нового AppDomain за тесты, которые не заботятся о глобальном состоянии ( Подавляющее большинство моих тестов).
Решение
В конце я написал помощника, который использовал AppDomain .CreateDomain , а затем использовал рефлексию для вызова модульного теста под другим доменом приложения. Это обеспечивает необходимую изоляцию.
Этот пост на форумах MSDN показывает, как справиться с ситуацией, если у вас есть только несколько статических параметров, которые необходимо сбросить. Это упоминаются некоторые варианты (например, использование Reflection и PrivateType ).
Я продолжаю приветствовать любые дальнейшие идеи, особенно если я упускаю что-то очевидное в MSTEST.
Другие советы
Добавьте в свои тесты помощника, который использует отражение для удаления экземпляра синглтона (вы также можете добавить метод сброса к синглтону, но я буду обеспокоен его использованием). Что-то вроде:
public static class SingletonHelper {
public static void CleanDALFactory()
{
typeof(DalFactory)
.GetField("_instance",BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, null);
}
}
Вызовите это в вашем методе TestInitialize. [Я знаю, что это «очистка мира», но вам нужно написать метод только один раз в хелпер на единицу, это очень тривиально и дает вам явный контроль]
Я думаю, что вы ищете атрибут TestIntialize и атрибут TestCleanUp. Вот блог MSDN с ссылкой на порядок выполнения. текст
У нас была похожая проблема с нашими MSTests. Мы справились с этим, вызвав функцию в начале и в конце конкретных тестов, которые в ней нуждались. Р>
Мы сохраняем дату окончания теста в конфигурации нашего приложения. Три теста нуждались в этой дате, чтобы попасть в определенный диапазон, чтобы определить соответствующие значения. При настройке нашего приложения значения конфигурации будут сброшены только в том случае, если в сеансе не было назначено значение. Итак, мы создали две новые частные статические функции - одну для явного задания значения конфигурации на указанную дату и одну для очистки этой даты от сеанса после выполнения теста. В наших трех тестах мы назвали эти две функции. Когда запускается следующий тест, приложение видит пустое значение для даты и перезагружает его из файла конфигурации.
Я не уверен, что это полезно, но именно так мы обошли нашу похожую проблему.