NUnit 3: 禁止测试并行运行

31
我已安装最新的NUnit(3.2.0),并使我所有的测试并行运行。这可能看起来是期望的行为,但实际上它破坏了我的一些测试。我在[OneTimeSetUp]中有一些依赖于线程的初始化,似乎我无法强制NUnit按顺序运行我的测试。我阅读了文档,其中说明默认情况下不会并行运行测试,但实际上它们是会并行运行的!
此外,我尝试添加了以下属性:[assembly: Parallelizable(ParallelScope.None)] - 没有效果。
有人知道如何改变这种行为吗?
P.S. 我使用ReSharper运行它,但也尝试了MSVS插件。
UPD:我正在使用MVVM LightDispatcherHelper.Initialize()(在[OneTimeSetUp]内)存储稍后由几个测试使用的调度程序对象。如果线程不同(在测试和设置方法之间),则正在测试的操作将异步执行且我的测试失败。
我检查了不同测试中的线程ID,它们都不同。
UPD2:来自文档的摘录:
"NUnit 3.0框架可以在一个程序集内并行运行测试。这是与引擎并行测试执行完全独立的设施,尽管可以在同一测试运行中使用两者。
默认情况下不会进行任何并行执行。使用属性指示哪些测试可以并行运行以及它们与其他测试的关系。"
如果这并不意味着除非明确指定,否则不应该并行运行程序集内的测试,则表示什么?为什么[assembly: Parallelizable(ParallelScope.None)]对测试的并行执行没有影响?
UPD3:问题的答案可能在下面找到,但如果您被 DispatcherHelper.Initialize()卡住(就像我一样),您只需要从OneTimeSetUp中删除此初始化,并将以下行放入每个使用调度程序的测试中:
DispatcherHelper.Reset();
DispatcherHelper.Initialize();

你的测试可能没有并行运行,很可能是因为它们在不同的线程中运行而不是在你的OneTimeSetup中。你是否在线程本地存储中存储信息? - Rob Prouse
另外,如果您或任何人有关于如何使用属性表达需要单个线程的想法,请在 GitHub 上提交一个功能请求(问题)! - Charlie
1
文档仅指出测试将按顺序或并行运行。你可以理解为这意味着它们在同一个线程上运行,但是内部实现可能需要测试在不同的线程上运行的许多原因。超时是一个例子,我们会生成一个线程并在测试超时时终止它,但还有许多其他情况。 - Rob Prouse
1
@ixSci,是的我知道这是底层发生的事情,我是团队的一员。在3.0.1和3.2之间有一个PR,导致更多的测试在它们自己的线程上运行,以解决一些关于超时和单元状态的错误,但即使在此之前,有些测试也会在不同的线程上运行。你可能之前只是碰巧运气好。抱歉... - Rob Prouse
1
针对@iXsci的更新评论,正如您所请求的那样:您引用的文档是正确的。 NUnit不会在没有您的允许下并行运行测试。这并不意味着它会在同一线程上运行所有测试。它可能会使用单独的线程,但会按顺序运行这些线程。 - Charlie
显示剩余7条评论
2个回答

28

你可以通过添加[NonParallelizable]属性来阻止测试并行运行,该属性可添加在测试、类和程序集级别上。


27

NUnit不能保证所有测试都在同一个线程上运行,因此您发现测试在不同的线程上运行并不意味着它们是并行运行的。

文档仅说明测试将按顺序或并行方式运行。您可能会认为这意味着它们在同一个线程上运行,但是内部实现可能需要测试在不同的线程上运行的许多原因。超时就是一个例子,我们会生成一个线程,如果测试超时则会终止它,但还有其他很多原因。

并行测试运行是NUnit 3中的新功能,因此内部实现与NUnit 2有所改变。一个强制所有测试在同一个线程上运行的属性可能会很有用,因此请随时提交增强请求

抱歉,我不熟悉MVVM Light,因此无法建议如何返回到OneTimeSetup线程。

更新 - 由于这是与Web和异步常见使用方式,NUnit团队已经决定提供一个属性,该属性将要求测试在与装置的OneTimeSetup相同的线程上运行。这将在下一个版本中发布,可能是3.4版或热修复3.2.1版。如果您想跟踪进度,请参阅问题拉取请求更新2 - 现在,您可以向TestFixture添加SingleThreadedAttribute,以指示运行程序OneTimeSetUpOneTimeTearDown和所有子测试必须在同一线程上运行。

3
谢谢您的回答。您不觉得应该提到即使在非并行方式下,测试也可能在不同的线程上运行吗?我认为这应该在一个突出的位置上提到。这个答案也应该有所帮助,因为现在很容易在谷歌上搜索到这样的行为,但我也认为文档应该以某种方式提到它。 - ixSci
事先编写此类文档很难,因为很难知道用户可能会做出什么样的假设。现在我们发现这个应该加入我们已经知道的其他内容中。 :-) - Charlie
6
我可以添加一个名为“你不能假设的事情”的文档页面 :-) 目前,这里有一些我多年来遇到的错误假设:(1) 不要假设 NUnit 只会在运行时调用一次您的构造函数 (2) 不要假设您的测试正在运行在唯一的线程上 - 尽管您可以要求 NUnit 这样做 (3) 不要假设您的测试都在同一个线程上运行 (4) 不要假设您的测试按照源文件或字母顺序运行。请在 Github 上发布关于此类页面的建议,https:github.com/nunit/docs - Charlie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接