何时使用 TestFixtureSetUp 属性而不是默认构造函数?
NUnit 文档没有告诉我何时使用带有 TestFixtureSetup 的方法以及何时在构造函数中进行设置。
public class MyTest
{
private MyClass myClass;
public MyTest()
{
myClass = new MyClass();
}
[TestFixtureSetUp]
public void Init()
{
myClass = new MyClass();
}
}
TestFixtureSetup
与默认构造函数相比有什么好的/坏的做法,或者没有任何区别?
The NUnit documentation doesn't tell me when to use a method with a TestFixtureSetup
and when to do the setup in the constructor.
public class MyTest
{
private MyClass myClass;
public MyTest()
{
myClass = new MyClass();
}
[TestFixtureSetUp]
public void Init()
{
myClass = new MyClass();
}
}
Are there any good/bad practices about the TestFixtureSetup
versus default constructor or isn't there any difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
为什么需要在测试类中使用构造函数?
我使用
[SetUp]
和[TearDown]
标记方法在每次测试之前和之后执行代码,类似地[TestFixtureSetUp]
和 < code>[TestFixtureTearDown] 标记了在夹具中的所有测试运行之前和之后仅执行一次的代码方法。我想您可能可以用
[TestFixtureSetUp]
替换构造函数(尽管我没有尝试过),但这似乎只是打破了标记方法提供的明确约定。Why would you need to use a constructor in your test classes?
I use
[SetUp]
and[TearDown]
marked methods for code to be executed before and after each test, and similarly[TestFixtureSetUp]
and[TestFixtureTearDown]
marked methods for code to be executed only once before and after all test in the fixture have been run.I guess you could probably substitute the
[TestFixtureSetUp]
for a constructor (although I haven't tried), but this only seems to break from the clear convention that the marked methods provide.我认为这是 nUnit 团队尚未解决的问题之一。 然而,有一个优秀的 xUnit 项目 看到了这个确切的问题,并认为构造函数是一个很好用的东西测试夹具初始化。
对于 nunit,在这种情况下我的最佳实践是使用 TestFixtureSetUp、TestFixtureTearDown、SetUp 和 TearDown文档中描述的方法。
我认为,当我不将 nUnit 测试装置视为普通类时,即使您使用该构造来定义它,它也会对我有所帮助。 我认为它们是固定的,这让我克服了心理障碍,让我忽略了这个问题。
I think this has been one of the issues that hasn't been addressed by the nUnit team. However, there is the excellent xUnit project that saw this exact issue and decided that constructors were a good thing to use on test fixture initialization.
For nunit, my best practice in this case has been to use the
TestFixtureSetUp
,TestFixtureTearDown
,SetUp
, andTearDown
methods as described in the documentation.I think it also helps me when I don't think of an nUnit test fixture as a normal class, even though you are defining it with that construct. I think of them as fixtures, and that gets me over the mental hurdle and allows me to overlook this issue.
我经常想知道
[TestFixtureSetUp]
的需求是什么,因为有一个简单、易于理解的一流语言构造可以完成完全相同的事情。我的偏好是使用构造函数,利用 readonly 关键字确保成员变量无法重新初始化。
I have often wondered what the need for
[TestFixtureSetUp]
was, given that there is a simple, well understood first class language construct that does exactly the same thing.My preference is to use constructors, to take advantage of the readonly keyword ensuring member variables cannot be reinitialised.
在构造函数中可以使用
[TestFixtureSetup]
做的一件事是从[TestFixture]
接收参数。如果您想参数化您的测试装置,那么您将必须使用构造函数来进行至少某些的设置。 到目前为止,我仅将其用于集成测试,例如用于测试具有多个数据提供者的数据访问层:
One thing you can't do with
[TestFixtureSetup]
that you can do in the constructor is receive parameters from the[TestFixture]
.If you want to parameterise your test fixture, then you will have to use the constructor for at least some of the set-up. So far, I've only used this for integration tests, e.g. for testing a data access layer with multiple data providers:
构造函数和用
[TestFixtureSetUp]
属性标记的方法之间存在差异。 根据 NUnit 文档:因此,如果您有任何昂贵的初始化,最好使用 TestFixtureSetUp。
There is difference between constructor and method marked with
[TestFixtureSetUp]
attribute. According to NUnit documentation:So if you have any expensive initialization it is better to use
TestFixtureSetUp
.构造函数和 TestFixtureSetUp 之间的一个重要区别是,至少在 NUnit 2 中,构造函数代码实际上是在测试枚举上执行的,而不仅仅是测试运行,因此基本上您希望将 ctor 代码限制为仅填充只读(即参数)值。 任何导致副作用或做任何实际工作的事情都需要包装在 Lazy 中或在 TestFixtureSetUp / OneTimeSetUp 中完成。 因此,您可以将构造函数视为仅配置测试的地方。 而 TestFixtureSetUp 是测试夹具(测试运行之前系统所需的初始状态)初始化的地方。
An important difference between constructor and TestFixtureSetUp is that, in NUnit 2 at least, constructor code is actually executed on test enumeration, not just test running, so basically you want to limit ctor code to only populating readonly, i.e. parameter, values. Anything that causes side-effects or does any actual work needs to either be wrapped in a Lazy or done in the TestFixtureSetUp / OneTimeSetUp. So, you can think of the constructor as solely a place to configure the test. Whereas the TestFixtureSetUp is where the test fixture, the required initial state of the system before tests are run, is initialized.
[TestFixtureSetUp]
和[TestFixtureTearDown]
用于整个测试类。 仅运行一次。[SetUp]
和[TearDown]
适用于每种测试方法(test)。 为每个测试运行。[TestFixtureSetUp]
and[TestFixtureTearDown]
are for whole test class. runs only once.[SetUp]
and[TearDown]
are for every test method(test). runs for every test.我认为我有一个否定的好答案 - 使用构造函数而不是属性的原因是当您在测试类之间具有继承时。
只有一个用
[TestFixtureSetup]
注解的方法将被调用(仅在具体类上),但其他夹具初始值设定项不会。 在这种情况下,我宁愿将初始化放在构造函数中,它具有明确定义的继承语义:)I think I have a negative good answer - the reason to use a constructor instead of the attribute is when you have an inheritence between test classes.
Only one method annotated with
[TestFixtureSetup]
will be called (on the concrete class only), but the other fixture initializers will not. In this case I'd rather put the initialization in the constructor, which has a well-defined semantics for inheritance :)[SetUp] 的方法可能是异步的。 构造函数不能。
The method with [SetUp] may be async. The constructor can not be.
构造函数和
SetUp
方法的使用方式不同:构造函数仅运行一次。
但是,在执行每个测试用例之前,
SetUp
方法会运行多次。The constructor and the
SetUp
methods are used differently:The constructor is run only once.
However, the
SetUp
methods are run multiple times, before every test case is executed.