我有一个使用NUnit编写的大型验收测试套件(每个测试约需要10秒)。我想利用我的机器都是多核心的优势。理想情况下,我想让每个核心独立运行一个测试,而不影响其他测试。
虽然有PNUnit,但它是为测试线程同步问题等方面设计的,我没有看到明显的方法可以实现此目标。
是否有开关/工具/选项可供我使用以并行运行测试?
我有一个使用NUnit编写的大型验收测试套件(每个测试约需要10秒)。我想利用我的机器都是多核心的优势。理想情况下,我想让每个核心独立运行一个测试,而不影响其他测试。
虽然有PNUnit,但它是为测试线程同步问题等方面设计的,我没有看到明显的方法可以实现此目标。
是否有开关/工具/选项可供我使用以并行运行测试?
如果您想并行运行NUnit测试,至少有两个选项:
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 和它的命令行测试运行工具来获得最大的测试运行性能。它无与伦比,同时还会彻底改变您的代码-测试-调试循环。
// Make all tests in the test assembly run in parallel
[assembly: Parallelizable(ParallelScope.Fixtures)]
[assembly: Parallelizable(ParallelScope.All)]
。 - Ned[assembly: Parallelizable(ParallelScope.ContextMask)]
ContextMask没有文档记录,但是如果您打开Enum,您会发现
ContextMask = (ParallelScope.Fixtures | ParallelScope.Children)
这意味着除非您为特定的类、方法或测试设置不同的值,否则此程序集中存在的每个单元测试都将被视为可并行化。 - Moscatonunit-console-x86.exe Model.dll Test.dll /exclude:MyCategory /xml=TestResults.xml /framework=net-4.0 /noshadow
nunit-console-x86.exe Model.dll Test.dll /include:MyCategory /xml=TestResults.xml /framework=net-4.0 /noshadow
如果我们按顺序执行这些命令,两个都会成功运行。但是如果我们并行执行它们,只有一个会成功。据我所知,它是首先加载测试夹具的那个。另一个会失败,并显示“无法找到固定装置”的消息。现在您可以使用NCrunch来并行执行单元测试,甚至可以配置NCrunch使用多少核心以及Visual Studio使用多少核心。
此外,您还可以获得连续测试的额外优势 :)
克隆带有单元测试的文件夹(如果您的测试更改本地数据),
同步测试(例如,如果您的测试在testfixtureteardown上杀死所有开发服务器或chromerunner用于qunit),
x86模式和管理员权限以运行测试,
批量运行-您可以并行运行多个程序集的测试,
即使是单线程运行,也比标准nunit运行器快,如果您有许多小型测试。
此外,该工具支持命令行测试运行程序(用于并行运行),您可以将其与持续集成一起使用。
这可能有点作弊,但你可以将单元测试分成多个类别。然后,为每个类别启动一个新的 NUnit 实例。
编辑:看起来他们已经在控制台应用程序中添加了 /process 选项。命令行帮助说明这是“测试的进程模型:单个、独立、多个”。测试运行器似乎也具备此功能。
编辑2:不幸的是,虽然它确实为每个程序集创建了单独的进程,但进程隔离选项(命令行中的 /process)一次只运行一个代理。