How to run unit tests (MSTest) in parallel?

78,482

Solution 1

Most of the answers on this page forget to mention that MSTest parallelizes tests in separate assemblies. You have to split your unittests into multiple .dll's to paralelize it.

But! The recent version - MSTest V2 - now CAN parallelize "in-assembly" (yay!) you just need to install a couple of nuget packages in your test project - TestFramework and TestAdapter - like described here https://blogs.msdn.microsoft.com/devops/2018/01/30/mstest-v2-in-assembly-parallel-test-execution/

And then simply add this to your test project

[assembly: Parallelize(Workers = 4, Scope = ExecutionScope.ClassLevel)]

EDIT: You can also disable parallel execution for a specific test using [DoNotParallelize] on a test method.

Solution 2

You can get up to 5 by using the method from the Visual Studio Team Test Blog

Keep in mind that there may be concurrency issues using this, as MSTest doesn't completely isolate each test (statics carry over, for example, making things interesting for code meant to run once).

(No idea why the limit is 5, but MSTest will not run them in parallel if parallelTestCount is set to more than 5. As per the comments below, this rule apparently changes with Visual Studio 2013)

Solution 3

Visual Studio 2015 Update 1 adds this. https://docs.microsoft.com/visualstudio/releasenotes/vs2015-update1-vs#misc

For Update 2, there is a UI toggle button in the toolbar at the top of the Test Explorer pane (between the 'grouping' and 'search' boxes).

For Update 1, Set the following in the .runsettings

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
  <RunConfiguration>
    <MaxCpuCount>0</MaxCpuCount>
   </RunConfiguration>
</RunSettings>

The value for MaxCpuCount has the following semantics:

• ‘n’ (where 1 <= n <= number of cores) : upto ‘n’ processes will be launched.

• ‘n’ of any other value : The number of processes launched will be as many as the available cores on the machine.

Note also for MSTest V2, you can apply parallelism at the class level, either with assembly directives:

[assembly: Parallelize(Workers = 3, Scope = ExecutionScope.ClassLevel)]

or the .runsettings:

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
  <!-- MSTest adapter -->
  <MSTest>
    <Parallelize>
      <Workers>4</Workers>
      <Scope>ClassLevel</Scope>
    </Parallelize>
  </MSTest>
</RunSettings>

An assembly, class, or method can opt out with [DoNotParallelize]

See https://github.com/Microsoft/testfx-docs/blob/master/RFCs/004-In-Assembly-Parallel-Execution.md

Solution 4

What I found is that C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe will run parallel tests with a .testsettings file which looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="TestSettings1" id="21859d0f-7bdc-4165-b9ad-05fc803c9ee9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
  <Description>These are default test settings for a local test run.</Description>
  <Deployment enabled="false" />
  <Execution parallelTestCount="8">
    <TestTypeSpecific>
      <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">
        <AssemblyResolution>
          <TestDirectory useLoadContext="true" />
        </AssemblyResolution>
      </UnitTestRunConfig>
    </TestTypeSpecific>
    <AgentRule name="Execution Agents">
    </AgentRule>
  </Execution>
</TestSettings>

Reference can be found here http://msdn.microsoft.com/en-us/library/vstudio/jj155796.aspx

Solution 5

The above answers definitely helped clarify things for me, but, this point from John Koerner's blog: https://johnkoerner.com/vs2015/parallel-test-execution-in-visual-studio-2015-update-1-might-not-be-what-you-expect/ was the bit we were missing.

"Parallel test execution leverages the available cores on the machine, and is realized by launching the test execution engine on each available core as a distinct process, and handing it a container (assembly, DLL, or relevant artifact containing the tests to execute), worth of tests to execute."

--> "The separate container bit is the piece I was missing. In order to get my tests to run in parallel, I needed to split up my tests into separate test assemblies. After doing that, I saw that the tests in different assemblies were running in parallel."

So yeah, we got the tests running in parallel in VSTS by using their handy 'run in parallel' flag, but it wasn't enough, we had to split our tests up into separate test projects. Logically grouped of course, not a project-per-test which would be ridiculous

Share:
78,482
Bogdan Gavril MSFT
Author by

Bogdan Gavril MSFT

I am a software developer tired of updating this profile. But I try to keep LinkedIn up to date, so ... https://www.linkedin.com/in/bgavril/ A lot of my work is open source: https://github.com/bgavrilMS

Updated on November 06, 2021

Comments

  • Bogdan Gavril MSFT
    Bogdan Gavril MSFT over 2 years

    I am looking for ways to run test suites in parallel.

    I am aware of .testrunconfig setting. This allows you to multiplex on the number of CPUs.

    I want to run 1000 tests in parallel. This makes sense because I am testing a web service, so 90% of the time spent in a test is waiting for the service to respond.

    Any ideas on how to pull this off ? The tests are written for VS, but I am open to running them outside of VS.

    Later edit: the Visual Studio test team have added this in VS 2015 Update 1. See Mark Sowul's answer bellow.

  • Bogdan Gavril MSFT
    Bogdan Gavril MSFT over 13 years
    Yup, just found that the hard way :) - I ran my suite on a 8 core and all tests were aborted...
  • Anttu
    Anttu about 11 years
    It shouldn't be limited to 5 in total, but 5 hung tests. Bruce Taimana's comment: "Should that clean up "hang" or take too long, we let it continue to cleanup but we kick off the next test in parallel. If you reach 5 "hung" tests, we abort." Read the whole comment here.
  • Rangoric
    Rangoric about 11 years
    @Anttu I would want to see a solution that is set up to run more than 5 at once and have it actually run them instead of failing. Each time I've tried to have more than 5 for that setting it would just fail. Maybe the time for a hang is considered to be too small? I don't really know.
  • Leniel Maccaferri
    Leniel Maccaferri almost 10 years
    It also works if you use the Test Explorer when within Visual Studio. You only need to pick the .testsettings configured with parallelTestCount. More details here: ardalis.com/… By the way: to pick the .testsettings, click the TEST menu in VS 2013 then Test Settings => Select Test Settings File.
  • Jonathan Allen
    Jonathan Allen over 9 years
    I've never seen such a beast. In 2013 I had to create my own test settings file (Add Item at the Solution level), then modify it for parallel support as per Igor's instructions.
  • Nir
    Nir almost 9 years
    I'm using MSTest 12.0.21005.1 (Visual studio 2013) and there is no thread limit.
  • GilesDMiddleton
    GilesDMiddleton about 8 years
    We have test DLLs with hundreds of tests, some can run parallel, some can't. Is there a way of attributing safe and unsafe test classes/methods? I typically want to select one or more of these huge DLLs and let it rip.
  • Mark Sowul
    Mark Sowul about 8 years
    One thing to keep in mind is that the parallelism is on the class level, not the test level. I don't see a built-in way to do what you want, but you could do it yourself, e.g. with named Mutexes in ClassInitialize/ClassCleanup. Unfortunately you could end up with those tests blocking the parallelism for a while (e.g. all four 'parallel tests' are ones that use the mutex), but that's as good as I think you can get.
  • jessehouwing
    jessehouwing almost 8 years
    Tests are parallelized at the container level (in case of C#, that's Assembly), so it will run tests from different assemblies in parallel. Tests in the same assembly are executed in sequence in the new model.
  • Gusdor
    Gusdor almost 8 years
    @jessehouwing I have observed parallelism at the class level with massive speed differences. I think there is some hidden logic that decides how to parallelize the tests.
  • A X
    A X about 4 years
    Where does one place this snippet?
  • Alex from Jitbit
    Alex from Jitbit about 4 years
    @Abr usually assembly-wide attributes are placed in AssemblyInfo.cs but actually you put this in any file, up to you.
  • Dongolo Jeno
    Dongolo Jeno almost 3 years
    In some cases the file is not picked up automatically even it it is there and named correctly but than than you can configure to be picked up from Visual studio menu Test -> Configure Run Settings-> Select Solution Wide runsettings file. (Browse to file)