developer tip

NUnit 테스트를 병렬로 실행하려면 어떻게해야합니까?

optionbox 2020. 10. 17. 10:25
반응형

NUnit 테스트를 병렬로 실행하려면 어떻게해야합니까?


NUnit을 사용하여 작성된 대규모 수용 테스트 (테스트 당 최대 10 초) 테스트 스위트가 있습니다. 내 컴퓨터가 모두 다중 코어 박스라는 사실을 활용하고 싶습니다. 이상적으로는 다른 테스트와 독립적으로 코어 당 하나의 테스트를 실행할 수 있습니다.

PNUnit이 있지만 스레딩 동기화 문제 등을 테스트하기 위해 설계되었으며이를 수행하는 명확한 방법을 보지 못했습니다.

테스트를 병렬로 실행하는 데 사용할 수있는 스위치 / 도구 / 옵션이 있습니까?


NUnit 테스트를 병렬로 실행하려면 최소한 두 가지 옵션이 있습니다.

  • NCrunch는 즉시 사용할 수 있습니다 (아무것도 변경하지 않고 상용 제품 임).
  • NUnit 3은 병렬로 실행할 수있는 테스트를 표시하는 데 사용할 수있는 병렬화 가능한 속성을 제공합니다.

NUnit 버전 3은 병렬 테스트 실행을 지원합니다.

클래스에 속성 추가 : [Parallelizable(ParallelScope.Self)]테스트를 병렬로 실행합니다.

• ParallelScope.None은 테스트가 다른 테스트와 병렬로 실행되지 않을 수 있음을 나타냅니다.

• ParallelScope.Self는 테스트 자체가 다른 테스트와 병렬로 실행될 수 있음을 나타냅니다.

• ParallelScope.Children은 테스트의 하위 항목이 서로에 대해 병렬로 실행될 수 있음을 나타냅니다.

• ParallelScope.Fixtures는 조명기가 서로 병렬로 실행될 수 있음을 나타냅니다.

NUnit 프레임 워크-병렬 테스트-실행


프로젝트에 여러 테스트 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 및 명령 줄 테스트 실행 도구를 적극 권장 합니다. 이와 같은 것은 없으며 코드-테스트-디버그주기를 동시에 혁신 할 것입니다.


에서 이 문서 시험을 가속화하기 위해 포스터 명령 매개 변수는 각 인스턴스 실행해야 테스트하는 지정와 NUnit과의 여러 인스턴스를 실행하는 것을 언급한다.

FTA :

이상한 문제가 발생했습니다.

nunit-console을 사용하여 지속적 통합 서버에서 테스트를 실행합니다. 최근 우리는 Nunit 2.4.8에서 2.5.5로, .Net 3.5에서 4.0으로 이동했습니다. 테스트 실행 속도를 높이기 위해 다른 명령 줄 인수와 병렬로 Nunit의 여러 인스턴스를 실행합니다.

  • We have two copies of our test assemblies and the nunit binaries in folder A and B.
  • In folder A we execute

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

  • In folder B we execute

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

If we execute the commands in sequence both run successfully. But if we execute them in parallel only one succeeds. As far as I can tell it's the one that first loads the test fixtures. The other fails with the message "Unable to locate fixture".

Is this problem already known? I could not find anything related in the bug list on launchpad. BTW Our server runs Windows Server 2008 64-bit. I could also reproduce the problem on Windows 7 64-bit.

Assuming this bug is fixed or you are not running the newer version(s) of the software mentioned you should be able to replicate their technique.

Update

TeamCity looks like a tool you can use to automatically run NUnit tests. They have an NUnit launcher discussed here that could be used to launch multiple NUnit instances. Here is a blog post discussing the mergind of multiple NUnit XML results into a single result file.

So theoretically you could have TeamCity automatically launch multiple NUnit tests based on however you want to split up the workload and then merge the results into a single file for post test processing.

Is that automated enough for your needs?


Just because PNUnit can do synchronization inside test code doesn't mean that you actually have to use that aspect. As far as I can see there's nothing to prevent you from just spawning a set and ignoring the rest till you need it.

BTW I don't have the time to read all of their source but was curious to check out the Barrier class and it's a very simple lock counter. It just waits till N threads enter and then sends the pulse for all of them to continue running at the same time. That's all there is to it - if you don't touch it, it won't bite you.

Might be a bit counter intuitive for a normal threaded development (locks are normally used to serialize access - 1 by 1) but it is quite a spirited diversion :-)


You can now use NCrunch to parallelize your unit tests and you can even configure how many cores should be used by NCrunch and how many should be used by Visual Studio.

plus you get continuous testing as a bonus :)


It would be a bit of a hack, but you could split the unit tests into a number of categories. Then, start up a new instance of NUnit for each category.

Edit: It looks like they have added a /process option to the console app. The command-line help states this is the "Process model for tests: Single, Separate, Multiple". The test runner also appears to have this feature.

Edit 2: Unfortunately, although it does create separate processes for each assembly, the process isolation option (/process from the command line) runs the agents one at a time.


Since the project hasn't been mentioned here, I would like to bring up NUnit.Multicore. I haven't tried the project myself, but it seems to have an interesting approach to the parallel test problem with NUnit.


You can try my small tool TBox or console parallel Runner or even plugin to do distributed calulations, which also can run unit tests on the set of PCs SkyNet

TBox is created to simplify work with big solutions, which contains many projects. It supports many plugins and one of them provide ability to run NUnit tests in parallel. This plugin does not require any changes to your existing tests.

Also it support:

  • Cloning of the folder with unit test (if your tests changes local data),

  • Synchronizations of the tests (for example if your tests on testfixtureteardown kills all dev servers or chromerunner for qunit )

  • x86 mode and Admin privileges to run tests

  • Batch run - you can run tests for many assemblies in parallel

  • Even for single thread run, works faster than standart nunit runner, if you have much small tests.

Also this tool supports command line tests runner (for parallel run) and you can use it with continuous integration.



I have successfully used NUnit 3.0.0 beta-4 to run tests in parallel

  • Runs on build server
  • Runs Selenium tests
  • Has Visual Studio support
  • no Resharper support yet

Thanks for peers answer.

Gotchas:

  • Parallelizable attribute is not inherited, so it has to be specified on the test class.

You can use following PowerShell command (for NUnit3, for NUnit2 change runner name):

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

Presented command runs all test assemblies in single nunit instance, which allows to leverage engine built-in parallel test run.

Remarks

  1. Remember to tweak directory search pattern. Given example runs only assemblies ending with .Tests.dll and inside \bin\Debug directories.

  2. Be aware of Unique filtering - you may not want to have it.


As an alternative to adding the Parallelizable attribute to every test class:

Add this into the test project AssemblyInfo.cs class for nunit3 or greater:

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

참고URL : https://stackoverflow.com/questions/3313163/how-can-i-run-nunit-tests-in-parallel

반응형