Вы используете TestInitialize или конструктор тестового класса для подготовки каждого теста? и почему?


этот вопрос касается модульного тестирования в Visual Studio с использованием MSTest (это важно, потому что MSTest порядок выполнения). Как метод с пометкой [TestInitialize], так и конструктор тестового класса будут выполняться перед каждым методом тестирования.

Итак, вопрос в том, что вы склонны делать в каждой из этих областей? Вы избегаете выполнения определенных действий в любом из них? Какова ваша причина: стиль, технические, суеверия?

8 58

8 ответов:

конструктор-это просто структура, предоставляемая языком. Каждый тестовый фреймворк, похоже, имеет свой собственный контролируемый жизненный цикл "инициализировать". Вы, вероятно, только попадете в беду, используя конструктор для мутации ваших местных жителей.

MSTest: вы получаете совершенно новый экземпляр тестового класса для каждого TestMethod. Это может быть единственный случай, когда можно изменить локальные объекты в конструкторе, инициализаторе или методе тестирования и не влиять на другой тест методы.

public class TestsForWhatever
{
    public TestsForWhatever()
    {
        // You get one of these per test method, yay!
    }

    [TestInitialize] 
    public void Initialize() 
    {
        // and one of these too! 
    }

    [TestMethod]
    public void AssertItDoesSomething() { }

    [TestMethod]
    public void AssertItDoesSomethingElse() { }
}

MSpec: вы получаете только один Establish и Because для всех своих утверждений (It). Итак, не мутируйте своих местных жителей в своих утверждениях. И не зависите от мутаций местных жителей в базовых контекстах (если вы их используете).

[Subject(typeof(Whatever))]
public class When_doing_whatever
{
    Establish context = () => 
    { 
        // one of these for all your Its
    };

    Because of = () => _subject.DoWhatever();

    It should_do_something;
    It should_do_something_else;
}

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

вот некоторые преимущества, которые я нашел с Используя.

  • некоторые переменные среды (например, TestContext) недоступны до тех пор, пока не будет создан экземпляр тестового класса.
  • может потребоваться реализация с производным классом путем маркировки базового метода TestInitialize аннотация.
  • можно легко переопределить базовый метод TestInitialize и определить, следует ли вызывать базовый impl до производного impl, после или вообще. Напротив, если вы производите a тестовый класс из базового тестового класса, в случае конструктора без параметров, базовый ctor будет вызван независимо от того, намеревался ли он или нет.
  • его явное определение делает намерения ясными и дополняет метод TestCleanup. Вы можете утверждать, что вы можете создать деструктор для каждого конструктора, но это не гарантирует, что MS Test будет обрабатывать деструкторы, как вы ожидаете.

Я предпочитаю использовать [TestInitialize] метод для выполнения создания экземпляра тестируемого объекта и его параметров. Я выполняю работу в конструкторе только в том случае, если необходимо создать экземпляр базового класса тестирования (обычно это место, где я создаю или обновляю репозитории и т. д.). Это помогает мне сохранить код платформы тестирования и тестовый код отдельно логически и физически.

этот вопрос также задается (позже) в в чем разница между использованием конструктора в VS Testing framework и атрибутом TestInitialize ()?

FWIW я предполагаю, что под "конструктором класса" вы подразумеваете конструктор экземпляра (а не статический конструктор).

Я считаю, что тот же вопрос, который вы задаете, можно одинаково задать о статическом конструкторе против ClassInitialize...

тестируемый объект не должен быть создан в методе [TestInitialize]. Вы можете проверить конструктор вашего объекта в тестовом методе [Test].

объект в [TestInitialize] может быть настроен для вашего хранилища Persistence или для подготовки значения, которое тестируемый объект будет использоваться в тестах.

Я говорю использовать конструктор, если вам не нужно TestContext.

  1. если вы можете держать вещи простыми, то почему нет. Конструктор проще, чем магический атрибут.
  2. можно использовать readonly что является большой вещью в инициализации теста, где вы хотите подготовить материал для тестов, которые они не должны изменять (в идеале материал, который вы готовите, тоже будет неизменным).

Это зависит от сценария. Если у вас есть тестовый класс, и по какой-то странной причине, если вам нужно создать экземпляр его на другом тестовом классе, вам нужно будет использовать конструктор.

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