Когда я могу использовать атрибут TestFixtureSetUp вместо конструктора по умолчанию?


документация NUnit не говорит мне, когда использовать метод с TestFixtureSetup и когда делать настройку в конструкторе.

public class MyTest
{
    private MyClass myClass;

    public MyTest()
    {
        myClass = new MyClass();
    }

    [TestFixtureSetUp]
    public void Init()
    {
        myClass = new MyClass();
    }
}

есть ли какие-либо хорошие / плохие практики о TestFixtureSetup по сравнению с конструктором по умолчанию или нет никакой разницы?

9 65

9 ответов:

Я думаю, что это был один из вопросов, который не был решен командой nUnit. Тем не менее, есть отличный проект xUnit который увидел эту точную проблему и решил, что конструкторы были хорошей вещью для использования на инициализация тестового прибора.

для nunit, моя лучшая практика в этом случае была использовать TestFixtureSetUp,TestFixtureTearDown,SetUp и TearDown методы, описанные в документации.

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

зачем вам нужно использовать конструктор в тестовых классах?

я использую [SetUp] и [TearDown] отмеченные методы для кода, который будет выполняться до и после каждого теста, и аналогично [TestFixtureSetUp] и [TestFixtureTearDown] отмеченные методы для кода, который будет выполнен только один раз до и после того, как все тесты в приборе были запущены.

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

одна вещь, вы не можете сделать с [TestFixtureSetup] что вы можете сделать в конструкторе-это получить параметры от [TestFixture] .

Если вы хотите параметризовать свой тестовый прибор, то вам придется использовать конструктор по крайней мере для некоторые настройки. До сих пор я использовал это только для интеграционных тестов, например для тестирования уровня доступа к данным с несколькими поставщиками данных:

[TestFixture("System.Data.SqlClient",
  "Server=(local)\SQLEXPRESS;Initial Catalog=MyTestDatabase;Integrated Security=True;Pooling=False"))]
[TestFixture("System.Data.SQLite", "Data Source=MyTestDatabase.s3db")])]
internal class MyDataAccessLayerIntegrationTests
{
    MyDataAccessLayerIntegrationTests(
        string dataProvider,
        string connectionString)
    {
        ...
    }
}

Я часто задавался вопросом, что нужно для [TestFixtureSetUp] было, учитывая, что есть простая, хорошо понятная конструкция языка первого класса, которая делает точно то же самое.

Я предпочитаю использовать конструкторы, чтобы воспользоваться ключевым словом readonly, гарантирующим, что переменные-члены не могут быть повторно инициализированы.

есть разница между конструктором и методом, отмеченным . Согласно документации NUnit:

желательно, чтобы конструктор не имел никаких побочных эффектов, так как NUnit может построить объект несколько раз в ходе сеанса.

Так что если у вас есть дорогие инициализации лучше использовать TestFixtureSetUp.

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

только один метод с аннотацией [TestFixtureSetup] будет вызван (только для конкретного класса), но другие инициализаторы крепления не будут. В этом случае я бы предпочел поместить инициализацию в конструктор, который имеет четко определенную семантику для наследования :)

важное различие между конструктором и TestFixtureSetUp заключается в том, что, по крайней мере, в NUnit 2 код конструктора фактически выполняется при перечислении тестов, а не только при выполнении тестов, поэтому в основном вы хотите ограничить код ctor только заполнением только для чтения, т. е. значений параметров. Все, что вызывает побочные эффекты или делает какую-либо фактическую работу, должно быть либо завернуто в ленивый, либо сделано в TestFixtureSetUp / OneTimeSetUp. Таким образом, вы можете думать о конструкторе только как о месте для настройки тест. В то время как TestFixtureSetUp-это место, где тестовое устройство, необходимое начальное состояние системы перед запуском тестов, инициализируется.

[TestFixtureSetUp] и [TestFixtureTearDown] для всего тестового класса. работает только один раз.

[SetUp] и [TearDown] для каждого метода испытаний(тестов). работает для каждого теста.

конструктор и SetUp методы используются по-разному:
Конструктор запускается только один раз.
Тем не менее,SetUp методы выполняются несколько раз, прежде чем каждый тест выполняется.