如何并行运行NUnit测试?


83

我有一个使用NUnit编写的大型验收测试(每个测试约10秒)。我想利用我的机器都是多个核心设备这一事实。理想情况下,我可以在每个内核上运行一个测试,而与其他测试无关。

有PNUnit,但是它是为测试线程同步问题之类而设计的,我没有找到一种明显的方法来实现。

是否可以使用开关/工具/选项并行运行测试?


甚至我也想了解更多。@Billy ONeal,如果找到答案,请发表答案。
PK 2010年

您说每个测试十秒钟,理想情况下每个内核运行一个测试。CPU是否需要大量测试?否则,应该可以同时运行更多程序。
马蒂亚斯·尼尔森

@Mattias:是的,测试需要占用大量CPU。
Billy ONeal 2010年

Answers:


52

如果要并行运行NUnit测试,则至少有两个选项:

  • NCrunch开箱即用(不做任何更改,但是商业产品)
  • NUnit 3提供了可并行化的属性,该属性可用于指示哪些测试可以并行运行

考虑到问题,这个答案似乎是错误的,而不是真正的答案。在我看来,NCrunch需要您的支持,并且应该是最重要的答案,因为它可以在同一或多个进程中并在一台或多台计算机上同时运行(NUnit)测试,并且可以从VS或构建服务器中进行。
chillitom 2015年

2
@chillitom NCrunch在回答此问题后发布,是一个不错的选择(因为它应该开箱即用,尽管对于某些人来说价格过高)。将来的其他选项可能包括NUnit 3,它可以提供并行运行的测试(根据github.com/nunit/dev/wiki/Roadmap)。
David_001 2015年

3
尽管这是最佳答案,但它不再像从前那样正确。Nunit 3.0在2015年底发布,现在具有Parallelizable属性。参考:github.com/nunit/nunit/wiki/Parallelizable-Attribute
pb。

36

NUnit版本3将支持并行运行测试:

将属性添加到类:[Parallelizable(ParallelScope.Self)]将并行运行测试。

•ParallelScope.None表示该测试不能与其他测试并行运行。

•ParallelScope.Self表示测试本身可以与其他测试并行运行。

•ParallelScope.Children指示测试的后代可以彼此并行运行。

•ParallelScope.Fixtures指示灯具可以彼此并行运行。

NUnit框架并行测试执行


10

如果您的项目包含多个测试DLL,则可以使用此MSBuild脚本并行运行它们。显然,您需要调整路径以适合您的项目布局。

要与8个核心一起运行,请执行以下操作: c:\proj> msbuild /m:8 RunTests.xml

RunTests.xml

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="RunTestsInParallel" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <Nunit Condition=" '$(Nunit)' == '' ">$(MSBuildProjectDirectory)\..\tools\nunit-console-x86.exe</Nunit>
  </PropertyGroup>

  <!-- see http://mikefourie.wordpress.com/2010/12/04/running-targets-in-parallel-in-msbuild/ -->

  <Target Name="RunTestsInParallel">
    <ItemGroup> 
      <TestDlls Include="..\bin\Tests\$(Configuration)\*.Tests.dll" />
    </ItemGroup>

    <ItemGroup> 
      <TempProjects Include="$(MSBuildProjectFile)" > 
        <Properties>TestDllFile=%(TestDlls.FullPath)</Properties> 
      </TempProjects> 
    </ItemGroup> 

    <MSBuild Projects="@(TempProjects)" BuildInParallel="true" Targets="RunOneTestDll" /> 
  </Target>

  <Target Name="RunOneTestDll"> 
    <Message Text="$(TestDllFile)" />
    <Exec Command="$(Nunit) /exclude=Integration $(TestDllFile)  /labels /xml:$(TestDllFile).results.xml"
      WorkingDirectory="$(MSBuildProjectDirectory)\..\bin\Tests\$(Configuration)" /> 
  </Target>

</Project>

更新 如果我现在回答这个问题,我强烈推荐NCrunch及其命令行测试运行工具,以实现最佳的测试运行性能。没有什么比它喜欢,它会同时改变您的代码-测试-调试周期。


1
这帮助我将单元测试的运行时间从3分钟减少到2分钟。我已经在2核CPU上进行了测试。
Dmitrii Lobanov 2014年

4

本文中,提到了为了加速测试,发帖人运行多个NUnit实例,并使用命令参数指定每个实例应运行哪些测试。

自由贸易协定:

我遇到了一个奇怪的问题。

我们使用nunit-console在我们的持续集成服务器上运行测试。最近,我们从Nunit 2.4.8迁移到2.5.5,从.Net 3.5迁移到4.0。为了加快测试执行速度,我们使用不同的命令行参数并行运行Nunit的多个实例

  • 在文件夹A和B中,我们有两个测试程序集副本以及nunit二进制文件。
  • 在文件夹A中,我们执行

nunit-console-x86.exe Model.dll Test.dll / exclude:MyCategory /xml=TestResults.xml /framework=net-4.0 / noshadow

  • 在文件夹B中,我们执行

nunit-console-x86.exe Model.dll Test.dll / include:MyCategory /xml=TestResults.xml /framework=net-4.0 / noshadow

如果我们按顺序执行命令,则两个命令都将成功运行。但是,如果我们并行执行它们,那么只有一个成功。据我所知,这是首先加载测试夹具的工具。另一个失败,并显示消息“无法找到夹具”。

这个问题已经知道了吗?在启动板的错误列表中找不到任何相关的内容。顺便说一句,我们的服务器运行Windows Server 2008 64位。我也可以在Windows 7 64位上重现该问题。

假设此错误已修复,或者您没有运行提到的软件的较新版本,则应该能够复制其技术。

更新资料

TeamCity看起来像可以用来自动运行NUnit测试的工具。他们有一个此处讨论的NUnit启动器,可用于启动多个NUnit实例。 是一篇博客文章,讨论将多个NUnit XML结果合并为一个结果文件。

因此,从理论上讲,您可以让TeamCity根据您的意愿自动启动多个NUnit测试,但是您希望分担工作负载,然后将结果合并到单个文件中以进行测试后处理。

自动化程度足以满足您的需求吗?


这与已经发布的有关类别的想法相同...我不想在这里的实例之间保持合理的相等运行时间。在执行此操作之前,我宁愿编写自己的NUnit运行程序。
Billy ONeal 2010年

据我所知,如果没有解决方法(例如运行多个实例),NUnit将不支持此功能。如果您想的话,您可以制作一个工具,将测试分成N组,并自动运行NUnit的N个实例,其中N是您拥有的处理器/内核的数量。这是我可以想到的使用NUnit进行某种自动化并行测试的唯一方法。
kniemczak

我添加了讨论TeamCity持续集成工具的更新,并包括一些有关如何使用该工具解决自动化需求的文章。
kniemczak 2010年

3

仅仅因为PNUnit可以在测试代码中进行同步并不意味着您实际上必须使用该方面。据我所知,没有什么可以阻止您仅生成一个集合而忽略其余的集合,直到您需要它为止。

顺便说一句,我没有时间阅读所有的源代码,但是很好奇地检查了Barrier类,这是一个非常简单的锁计数器。它只是等待N个线程进入,然后发送脉冲以使所有线程继续同时运行。这就是全部-如果您不触摸它,它就不会咬您。

对于正常的线程开发(可能是锁通常用于对访问进行序列化-1乘1),可能有点反常。


3

现在,您可以使用NCrunch并行化单元测试,甚至可以配置NCrunch应该使用多少个内核以及Visual Studio应该使用多少个内核。

另外,您还将获得连续测试作为奖励:)


3
当您在Visual Studio中使用NCrunch时,它很棒,但是当您尝试在构建服务器上并行化测试时,它却无济于事。
Paccc

3
NCrunch现在提供了一个命令行工具,该工具在构建服务器上可以很好地工作。
chillitom 2015年

3

作为向每个测试类添加Parallelizable属性的替代方法:

将其添加到nunit3或更高版本的测试项目AssemblyInfo.cs类中:

// Make all tests in the test assembly run in parallel
[assembly: Parallelizable(ParallelScope.Fixtures)]

2

可能有点麻烦,但是您可以将单元测试划分为多个类别。然后,为每个类别启动一个新的NUnit实例。

编辑:看来他们已经向控制台应用程序添加了/ process选项。命令行帮助指出这是“测试的过程模型:单个,单独,多个”。测试运行器似乎也具有此功能。

编辑2:不幸的是,尽管它确实为每个程序集创建了单独的进程,但是进程隔离选项(/命令行中的进程)一次运行一个代理。


2

由于这里没有提到该项目,因此我想提出NUnit.Multicore。我自己还没有尝试过该项目,但是它似乎对NUnit的并行测试问题有一种有趣的方法。


2

您可以尝试使用我的小型工具TBox或控制台并行Runner甚至插件来进行分布式计算,这也可以在一组SkyNet PC上运行单元测试

创建TBox的目的是简化包含多个项目的大型解决方案的工作。它支持许多插件,其中之一提供了并行运行NUnit测试的功能。此插件不需要对现有测试进行任何更改。

还支持:

  • 使用单元测试克隆文件夹(如果您的测试更改了本地数据),

  • 测试的同步(例如,如果对testfixtureteardown的测试杀死了所有开发服务器或qunit的chromerunner)

  • x86模式和管理员特权以运行测试

  • 批处理运行-您可以并行运行许多装配的测试

  • 如果您进行了很多小测试,即使是单线程运行,其运行速度也比标准的nunit运行器更快。

此工具还支持命令行测试运行程序(用于并行运行),您可以将其与持续集成一起使用。


如果您与此产品相关联,请披露此信息。您已经发布了许多指向这一点的东西。
布拉德·拉尔森

当然,TBox-是我自己的工具。我已经在业余时间写了它。如果在这里说关于免费工具的做法不好,我将删除此答案,这没问题:)
Alex H

我们只希望人们清楚他们所涉及的产品。如果您完全公开自己的话,那么为什么应该适当地解决问题所带来的问题,而又不要过分提倡,那么您的答案应该可以接受。
布拉德·拉尔森

@brad它是Codeplex上的开源代码,不确定为什么这里有问题。
dvallejo 2014年

@DanVallejo-作为一个开源项目是社区在发布后未将其删除的原因。我们在那里有更多的余地,但我们仍然要求您公开您与该项目的隶属关系,以便人们可以理解您的建议背后的背景。亚历克斯是在这里这样做的,所以他的回答非常正确。
布拉德·拉尔森


1

我已成功使用NUnit 3.0.0 beta-4并行运行测试

  • 在构建服务器上运行
  • 运行硒测试
  • 具有Visual Studio支持
  • 尚无Resharper支持

感谢同行的回答

陷阱:

  • Parallelizable属性不会继承,因此必须在测试类上指定它。

1
NUnit 3.0现已发布
Ralph Willgoss'1

0

您可以使用以下PowerShell命令(对于NUnit3,对于NUnit2更改运行程序名称):

PS> nunit3-console (ls -r *\bin\Debug\*.Tests.dll | % FullName | sort-object -Unique)

出现的命令在单个nunit实例中运行所有测试程序集,这允许利用引擎内置的并行测试运行

备注

  1. 记住要调整目录搜索模式。给定的示例仅运行以目录.Tests.dll和在\bin\Debug目录内部结尾的程序集。

  2. 请注意Unique过滤-您可能不想拥有它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.