Как заставить MSTest TestMethod сбросить все синглеты / статики перед запуском?


Я использую 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
    }

Хотя аналогичный вопрос возник по этой теме, он лишь уточнил, что тесты не выполняются параллельно. Я понимаю, что тесты работают последовательно, но, похоже, нет способа явно принудительно создать новый домен приложения для каждого метода (или что-то эквивалентное очистке всех состояний).

В идеале я хотел бы указать это поведение только для небольшого подмножества моих модульных тестов, чтобы мне не пришлось платить штраф за создание нового домена приложения для тестов, которые не заботятся о глобальном состоянии (подавляющее большинство моих тестов).

4 10

4 ответа:

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

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

Я по-прежнему приветствую любые дальнейшие идеи, особенно если я пропал без вести. что-то очевидное в МСТЕСТЕ.

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

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

Вызов этого метода используя. [ Я знаю, что это "очистка мира", но вам нужно только написать метод один раз в помощнике на синглтон, его очень тривиальный и дает вам явный контроль ]

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

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

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

Я не уверен, что это полезно, но именно так мы работали над нашей аналогичной проблемой.