Как заставить MSTEST TestMethod сбросить все синглтоны / статики до запуска? - PullRequest
13 голосов
/ 11 октября 2008

Я использую 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 за тесты, которые не заботятся о глобальном состоянии ( Подавляющее большинство моих тестов).

Ответы [ 4 ]

7 голосов
/ 13 октября 2008

В конце я написал помощник, который использовал AppDomain.CreateDomain , а затем использовал рефлексию для вызова модульного теста под другим AppDomain. Он обеспечивает необходимую мне изоляцию.

Этот пост на форумах MSDN показывает, как справиться с ситуацией, если у вас есть только несколько статических параметров, которые необходимо сбросить. В нем упоминаются некоторые параметры (например, с помощью Reflection и PrivateType ).

Я продолжаю приветствовать любые дальнейшие идеи, особенно если я упускаю что-то очевидное в MSTEST.

6 голосов
/ 13 октября 2008

Добавьте в свои тесты помощника, который использует отражение для удаления экземпляра синглтона (вы также можете добавить метод сброса к синглтону, но я буду обеспокоен его использованием). Что-то вроде:

public static class SingletonHelper {
            public static void CleanDALFactory() 
            {
                    typeof(DalFactory)
                        .GetField("_instance",BindingFlags.Static | BindingFlags.NonPublic)
                        .SetValue(null, null);
            }
}

Вызовите это в вашем методе TestInitialize. [Я знаю, что это «очистка мира», но вам нужно написать метод только один раз в хелпер на единицу, это очень тривиально и дает вам явный контроль]

2 голосов
/ 13 октября 2008

Я думаю, что вы ищете атрибут TestIntialize и атрибут TestCleanUp. Вот блог MSDN, показывающий порядок выполнения текст ссылки

1 голос
/ 13 октября 2008

У нас была похожая проблема с нашими MSTests. Мы справились с этим, вызвав функцию в начале и в конце конкретных тестов, которые в ней нуждались.

Мы сохраняем дату окончания теста в нашей конфигурации приложения. Три теста нуждались в этой дате, чтобы попасть в определенный диапазон, чтобы определить соответствующие значения. При настройке нашего приложения значения конфигурации будут сброшены только в том случае, если в сеансе не было назначено значение. Итак, мы создали две новые частные статические функции - одну для явного задания значения конфигурации на указанную дату и одну для очистки этой даты из сеанса после выполнения теста. В наших трех тестах мы назвали эти две функции. Когда запускается следующий тест, приложение видит пустое значение для даты и перезагружает его из файла конфигурации.

Я не уверен, что это полезно, но именно так мы обошли нашу похожую проблему.

...