【问题标题】:NUnit 3: Forbid tests to run in parallelNUnit 3:禁止测试并行运行
【发布时间】:2016-03-14 08:49:32
【问题描述】:

我安装了最新的 NUnit(3.2.0),并且我的所有测试都并行运行。它可能看起来像可取的行为,但我没有要求它,实际上它破坏了我的一些测试。我在[OneTimeSetUp] 中进行了一些初始化,这与线程相关,似乎我无法强制 NUnit 按顺序运行我的测试。我已经阅读了documentation,它指出默认情况下测试不是并行运行的,但实际上它们是并行运行的!

此外,我尝试添加以下属性:[assembly: Parallelizable(ParallelScope.None)] — 不走运。

有人知道如何改变这种行为吗?

附:我使用 ReSharper 运行它,但也尝试使用 MSVS 插件。


UPD: 我正在使用 MVVM Light DispatcherHelper.Initialize()(inside[OneTimeSetUp]) 来存储调度程序对象,该对象后来被几个测试使用。如果线程不同(在测试和设置方法之间),那么被测试的操作会异步执行,我的测试会失败。

我在不同的测试中检查了线程 ID,它们都是不同的。


UPD2:摘自文档:

NUnit 3.0 框架可以在一个 组装。这是一个完全独立于引擎的设施 并行测试执行,尽管可以在 相同的测试运行。

默认情况下不会发生并行执行。属性用于指示哪些测试可以并行运行以及它们如何相关 其他测试。

如果这并不意味着程序集中的测试不应该在明确指定之前并行运行,那么这意味着什么?为什么[assembly: Parallelizable(ParallelScope.None)] 对测试并行执行没有影响?


UPD3: 问题的答案可能在下面找到,但如果您(像我一样)被DispatcherHelper.Initialize() 卡住,您只需要从OneTimeSetUp 中删除此初始化,并在每个使用调度程序的测试中添加以下行:

DispatcherHelper.Reset();
DispatcherHelper.Initialize();

【问题讨论】:

  • 您的测试可能没有并行运行,很可能它们运行在与您的 OneTimeSetup 不同的线程中。您是否将信息存储在线程本地存储中?
  • 请解释您所说的“线程相关”是什么意思。NUnit 中没有任何东西可以保证测试在同一个线程上运行。
  • 文档仅说明测试将按顺序或并行运行。您可能会认为这意味着它们在同一个线程上运行,但内部实现可能需要测试在不同的测试上运行的原因有很多。超时就是一个例子,如果测试超时,我们会生成一个线程并终止它,但还有很多其他的。
  • @ixSci,是的,我知道这就是幕后发生的事情,我是团队所有者之一。在 3.0.1 和 3.2 之间有一个 PR,它导致更多的测试在它们自己的线程上运行,以解决一些诸如超时和公寓状态之类的错误,但即使在此之前,一些测试也会在不同的线程上运行。你以前可能只是走运了。对不起...
  • 根据@iXsci 的要求评论更新:您引用的文档是正确的。没有你的sayo,NUnit 不会并行运行测试。这并不意味着它将在同一个线程上运行它们。它可以使用单独的线程,但会按顺序运行这些线程。

标签: c# nunit nunit-3.0


【解决方案1】:

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

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

并行测试运行是 NUnit 3 的新功能,因此内部实现从 NUnit 2 更改。强制线程内的所有测试在同一线程上运行的属性可能很有用,因此请随时提交 enhancement request

抱歉,我对 MVVM Light 不熟悉,所以我无法建议如何编组回 OneTimeSetup 线程。

更新 - 由于这是 web 和 async 的常见用法,NUnit 团队决定提供一个属性,要求测试在与夹具的OneTimeSetup 相同的线程上运行。这将在下一个版本 3.4 或修补程序 3.2.1 版本中。如果您想跟踪进度,请参阅 issuepull request

更新 2 - 您现在可以将 SingleThreadedAttribute 添加到 TestFixture 以向运行器指示 OneTimeSetUpOneTimeTearDown 和所有子测试必须在同一线程上运行。

【讨论】:

  • 感谢您的回答。您不认为即使以非并行方式也可以在不同的线程上运行测试会很好吗?在某个显眼的地方,我想。这个答案也应该有所帮助,因为现在很容易用谷歌搜索这种行为,但我也认为文档应该以某种方式提及它。
  • 很难提前写出这种文档,因为很难知道用户会做出什么样的假设。所以现在我们看到这个应该加入我们已经知道的其他人。 :-)
  • 我可能会添加一个名为“您不得假设的事情”的文档页面 :-) 现在,这里有一堆我多年来遇到的错误假设:(1)不要假设NUnit 每次运行只调用一次构造函数(2)不要假设您的测试在唯一的线程上运行 - 尽管您可以要求 NUnit 这样做(3)不要假设您的测试都在同一个线程上运行(4) 不要假设您的测试都是按照它们在源文件中出现的顺序或按字母顺序运行的。说真的,请在github上发布对此类页面的建议,https:github.com/nunit/docs
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    相关资源
    最近更新 更多