MSTest, MyClassInitialize и переменные экземпляра - PullRequest
12 голосов
/ 14 марта 2012

Интересно, как лучше всего инициализировать переменные экземпляра в тестовом классе под MSTest.Допустим, у меня есть тестовый класс, в котором много накладных расходов на насмешку и настройку вспомогательных объектов.Я хочу сделать это один раз, вместо того, чтобы повторять один и тот же код в каждом тесте.Я думал о том, чтобы использовать метод MyClassInitialize для инициализации некоторых глобальных переменных экземпляра, к которым имеют доступ все тесты.Таким образом, я инициализирую глобальные переменные экземпляра один раз, и они просто используются каждым тестом при запуске.

К сожалению, метод MyClassInitialize является статическим, поэтому не может инициализировать глобальные переменные экземпляра.Я думал о том, чтобы сделать глобальные переменные экземпляра статичными, но, похоже, это не правильное решение.Затем я подумал о том, чтобы просто поместить код инициализации в конструктор самого тестового класса, но что-то внутри меня продолжает говорить, что MyClassInitialize - это то, что я должен использовать.Другой мыслью было бы использовать MyTestInitialize, поскольку этот метод не является статичным, но это будет создавать объект снова и снова с каждым тестом.Это уместно?

Существуют ли передовые методы использования переменных в тестах, когда эти переменные нужно инициализировать только один раз до запуска тестов?Ниже приведен надуманный пример того, о чем я говорю.

[TestClass()]
public class ProgramTest
{
    // this object requires extensive setup so would like to just do it once
    private SomeObjectThatIsUsedByAllTestsAndNeedsInitialization myObject;
    private TestContext testContextInstance;

    [ClassInitialize()]
    public static void MyClassInitialize(TestContext testContext)
    {
        // initializing SomeObjectThatIsUsedByAllTestsAndNeedsInitialization clearly will
        // not work here because this method is static.
    }

    [TestMethod()]
    public void Test1()
    {
        // use SomeObjectThatIsUsedByAllTestsAndNeedsInitialization here
    }

    [TestMethod()]
    public void Test2()
    {
        // use SomeObjectThatIsUsedByAllTestsAndNeedsInitialization here
    }

    [TestMethod()]
    public void Test3()
    {
        // use SomeObjectThatIsUsedByAllTestsAndNeedsInitialization here
    }
}

Ответы [ 3 ]

9 голосов
/ 14 марта 2012

Используйте [TestInitialize] и [TestCleanup], когда это возможно.Модульное тестирование должно быть быстрым и изолированным, поэтому самым чистым способом является инициализация и очистка для каждого теста.Это гарантирует, что результаты теста не зависят от другого теста.Когда инициализация теста занимает много времени, вы, вероятно, не были модульным тестом, а интеграционным тестом.

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

3 голосов
/ 15 марта 2012

В чем ваша проблема со статическим?

Если ваши ObjectThatIsUsedByAllTests действительно могут на 100% быть разделены между всеми вашими тестами, тогда сделайте его статическим и используйте ClassInitialize - вот для чего он.тогда вам нужно инициализировать его для каждого теста, для чего и предназначен TestInitialize.

1 голос
/ 15 марта 2012

Вы можете использовать ленивую инициализацию переменной экземпляра в каком-то другом классе. Не забывайте, однако, что MSTest создаст новый экземпляр класса test для каждого метода теста, который он запускает. Поэтому любые переменные в этом классе, которые вы хотите сохранить в разных тестовых методах, должны быть статическими.

...