我有一个使用NUnit编写的大型验收测试(每个测试约10秒)测试套件。我想利用我的机器都是多核盒的事实。理想情况下,我可以在每个核心运行一个测试,与其他测试无关。
有PNUnit,但它是为测试线程同步问题和类似的东西而设计的,我没有看到一个明显的方法来实现这一点。
是否有可用于并行运行测试的开关/工具/选项?
标准的nunit runner不支持并行运行测试。您可以创建自己的测试运行器以并行运行测试(使用当前的nunit测试)。我不确定为什么nunit团队还没有这样做过。
或者,MBUnit可以选择创建可并行化的测试,并且由于MBUnit具有与NUnit几乎相同的语法,因此可能不需要花费太多精力来进行切换。
编辑:正如评论中所述,尽管在撰写本文时这个答案是正确的,如果你想现在并行运行NUnit测试,至少有两个选项:
我已成功使用NUnit 3.0.0 beta-4并行运行测试
感谢peers answer。
陷阱:
您可以使用以下PowerShell命令(对于NUnit3,对于NUnit2更改运行程序名称):
PS> nunit3-console (ls -r *\bin\Debug\*.Tests.dll | % FullName | sort-object -Unique)
Presented命令在单个nunit实例中运行所有测试程序集,允许利用引擎built-in parallel test run。
备注
.Tests.dll
结尾和\bin\Debug
目录内的程序集。Unique
过滤 - 您可能不想拥有它。作为向每个测试类添加Parallelizable属性的替代方法:
将其添加到nunit3或更高版本的测试项目AssemblyInfo.cs类中:
// Make all tests in the test assembly run in parallel
[assembly: Parallelizable(ParallelScope.Fixtures)]
NUnit版本3将支持并行运行测试:
将属性添加到类:[Parallelizable(ParallelScope.Self)]
将并行运行您的测试。
•ParallelScope.None表示测试可能无法与其他测试并行运行。
•ParallelScope.Self表示测试本身可以与其他测试并行运行。
•ParallelScope.Children指示测试的后代可以相对于彼此并行运行。
•ParallelScope.Fixtures表示灯具可以彼此并行运行。
如果您的项目包含多个测试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及其命令行测试运行工具,以获得最大的测试运行性能。没有什么比这更好的了,它会同时彻底改变您的代码测试调试周期。
在this article中提到,为了加快测试,海报运行NUnit的多个实例,其中命令参数指定每个实例应运行的测试。
FTA:
我遇到了一个奇怪的问题。
我们使用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
如果我们按顺序执行命令,则两次成功运行。但是如果我们并行执行它们只有一个成功。据我所知,它首先加载测试夹具。另一个失败,显示消息“无法找到夹具”。
这个问题已经知道吗?我在启动板上的bug列表中找不到任何相关内容。 BTW我们的服务器运行Windows Server 2008 64位。我还可以在Windows 7 64位上重现该问题。
假设此错误已得到修复,或者您没有运行所提及软件的较新版本,那么您应该能够复制他们的技术。
更新
TeamCity看起来像是一个可以用来自动运行NUnit测试的工具。他们有一个NUnit启动器discussed here,可用于启动多个NUnit实例。 Here是一篇博客文章,讨论了将多个NUnit XML结果合并到一个结果文件中。
因此,从理论上讲,您可以让TeamCity自动启动多个NUnit测试,但是您希望拆分工作负载,然后将结果合并到一个文件中进行后期测试处理。
这是否足以满足您的需求?
仅仅因为PNUnit可以在测试代码中进行同步并不意味着您实际上必须使用该方面。据我所知,没有什么可以阻止你只是产生一套而忽略其余的直到你需要它。
顺便说一下,我没有时间阅读他们的所有来源,但很想看看Barrier类,这是一个非常简单的锁定计数器。它等待直到N个线程进入,然后发送所有脉冲的脉冲以继续同时运行。这就是它的全部 - 如果你不碰它,它就不会咬你。
对于正常的线程开发可能有点反直觉(锁通常用于序列化访问 - 1乘1)但它是一个相当激烈的转移:-)
您现在可以使用NCrunch来并行化您的单元测试,甚至可以配置NCrunch应该使用多少个核心以及Visual Studio应该使用多少核心。
加上你连续测试作为奖金:)
这将是一个黑客攻击,但你可以将单元测试分成几个categories。然后,为每个类别启动一个新的NUnit实例。
编辑:看起来他们已经在控制台应用程序中添加了/ process选项。命令行帮助说明这是“测试的过程模型:单个,单独,多个”。测试运行器似乎也具有此功能。
编辑2:不幸的是,虽然它确实为每个程序集创建了单独的进程,但是进程隔离选项(来自命令行的/ process)一次运行一个代理程序。
由于这里没有提到这个项目,我想提出NUnit.Multicore。我自己没有尝试过该项目,但似乎对NUnit的并行测试问题有一个有趣的方法。
您可以尝试我的小工具TBox或控制台并行Runner甚至插件来做分布式计算,这也可以在PC上运行单元测试SkyNet
TBox旨在简化包含许多项目的大型解决方案的工作。它支持许多插件,其中一个提供并行运行NUnit测试的能力。此插件不需要对现有测试进行任何更改。
它还支持:
此工具还支持命令行测试运行器(用于并行运行),您可以将其与持续集成一起使用。