何时使用 TestFixtureSetUp 属性而不是缺省构造函数?

NUnit 文档没有告诉我什么时候使用带有 TestFixtureSetup的方法,什么时候在构造函数中进行设置。

public class MyTest
{
private MyClass myClass;


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


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

TestFixtureSetup和缺省构造函数有什么好坏之分吗? 或者说没有什么区别?

45154 次浏览

为什么需要在测试类中使用构造函数?

我使用 [SetUp][TearDown]标记的方法在每次测试之前和之后执行代码,类似地,[TestFixtureSetUp][TestFixtureTearDown]标记的方法在 fixture 中的所有测试运行之前和之后只执行一次代码。

我想您可以用 [TestFixtureSetUp]代替构造函数(尽管我还没有尝试过) ,但是这似乎只是打破了标记方法提供的明确约定。

我认为这是 nUnit 团队没有解决的问题之一。然而,优秀的 XUnit 项目看到了这个问题,并决定在 测试夹具初始化测试夹具初始化上使用构造函数是一件好事。

对于 nunit,我在本例中的最佳实践是使用文档中描述的 TestFixtureSetUpTestFixtureTearDownSetUpTearDown方法。

我认为,当我不把 nUnit 测试 fixture 看作是一个普通类时,它也会对我有所帮助,即使您是用那个构造来定义它的。我认为他们是固定的,这让我克服了心理障碍,让我忽略了这个问题。

我经常想知道为什么需要 [TestFixtureSetUp],因为有一个简单的,易于理解的一流的语言结构,完全相同的事情。

我的偏好是使用构造函数,以利用只读关键字确保成员变量不能被重新初始化。

我想我有一个负面的好答案——使用构造函数而不是属性的原因是当您在测试类之间有一个继承时。

只有一个用 [TestFixtureSetup]注释的方法将被调用(仅在具体类上) ,但是其他 fixture 初始化器将不被调用。在这种情况下,我宁愿将初始化放在构造函数中,构造函数具有定义良好的继承语义:)

在构造函数中不能用 [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]属性的方法之间存在差异。根据 NUnit 文档:

建议构造函数不要有任何副作用,因为 NUnit 可能在会话过程中多次构造该对象。

因此,如果有任何昂贵的初始化,最好使用 TestFixtureSetUp

构造函数和 SetUp方法的用法不同:
构造函数只运行一次。
但是,在执行每个测试用例之前,会多次运行 SetUp方法。

[TestFixtureSetUp][TestFixtureTearDown]适用于整个测试类。只运行一次。

[SetUp][TearDown]适用于每个测试方法(测试)。运行每个测试。

构造函数和 TestFixtureSetUp 之间的一个重要区别是,至少在 NUnit 2中,构造函数代码实际上是在测试枚举上执行的,而不仅仅是测试运行,所以基本上您希望将 ctor 代码限制为只填充 readonly,即参数,值。任何导致副作用或做任何实际工作的事情都需要包装在 Lazy 中或在 TestFixtureSetUp/OneTimeSetUp 中完成。因此,您可以认为构造函数只是配置测试的一个地方。而 TestFixtureSetUp 是测试装备的初始化位置,测试装备是运行测试之前系统所需的初始状态。

具有[ SetUp ]的方法可能是异步的。构造函数不能是。