Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute unit tests serially (rather than in parallel)

People also ask

Should unit tests be run in parallel?

Running unit tests in parallel can significantly improve the speed at which they run. However, you have to make sure that one test does not affect another in any way. Else your tests are green most of the time, but sometimes one or more tests will fail. Both tests depend on IRepository .

Is the order of the test execution important?

The order of execution has to be independent between test cases. This gives you the chance to rearrange the test cases in clusters (e.g. short-, long-running) and retest single test cases. In most cases, this makes perfect sense.

Do unit tests run in parallel C#?

Unit tests run one at a time. There is no parallelism.

Do xUnit tests run in order?

Order alphabetically The xUnit test framework allows for more granularity and control of test run order.


Each test class is a unique test collection and tests under it will run in sequence, so if you put all of your tests in same collection then it will run sequentially.

In xUnit you can make following changes to achieve this:

Following will run in parallel:

namespace IntegrationTests
{
    public class Class1
    {
        [Fact]
        public void Test1()
        {
            Console.WriteLine("Test1 called");
        }

        [Fact]
        public void Test2()
        {
            Console.WriteLine("Test2 called");
        }
    }

    public class Class2
    {
        [Fact]
        public void Test3()
        {
            Console.WriteLine("Test3 called");
        }

        [Fact]
        public void Test4()
        {
            Console.WriteLine("Test4 called");
        }
    }
}

To make it sequential you just need to put both the test classes under same collection:

namespace IntegrationTests
{
    [Collection("Sequential")]
    public class Class1
    {
        [Fact]
        public void Test1()
        {
            Console.WriteLine("Test1 called");
        }

        [Fact]
        public void Test2()
        {
            Console.WriteLine("Test2 called");
        }
    }

    [Collection("Sequential")]
    public class Class2
    {
        [Fact]
        public void Test3()
        {
            Console.WriteLine("Test3 called");
        }

        [Fact]
        public void Test4()
        {
            Console.WriteLine("Test4 called");
        }
    }
}

For more info you can refer to this link


Important: This answer applies to .NET Framework. For dotnet core, see Dimitry's answer regarding xunit.runner.json.

All good unit tests should be 100% isolated. Using shared state (e.g. depending on a static property that is modified by each test) is regarded as bad practice.

Having said that, your question about running xUnit tests in sequence does have an answer! I encountered exactly the same issue because my system uses a static service locator (which is less than ideal).

By default xUnit 2.x runs all tests in parallel. This can be modified per-assembly by defining the CollectionBehavior in your AssemblyInfo.cs in your test project.

For per-assembly separation use:

using Xunit;
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]

or for no parallelization at all use:

[assembly: CollectionBehavior(DisableTestParallelization = true)]

The latter is probably the one you want. More information about parallelisation and configuration can be found on the xUnit documentation.


For .NET Core projects, create xunit.runner.json with:

{
  "parallelizeAssembly": false,
  "parallelizeTestCollections": false
}

Also, your csproj should contain

<ItemGroup>
  <None Update="xunit.runner.json"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

For old .Net Core projects, your project.json should contain

"buildOptions": {
  "copyToOutput": {
    "include": [ "xunit.runner.json" ]
  }
}

For .NET Core projects, you can configure xUnit with an xunit.runner.json file, as documented at https://xunit.net/docs/configuration-files.

The setting you need to change to stop parallel test execution is parallelizeTestCollections, which defaults to true:

Set this to true if the assembly is willing to run tests inside this assembly in parallel against each other. ... Set this to false to disable all parallelization within this test assembly.

JSON schema type: boolean
Default value: true

So a minimal xunit.runner.json for this purpose looks like

{
    "parallelizeTestCollections": false
}

As noted in the docs, remember to include this file in your build, either by:

  • Setting Copy to Output Directory to Copy if newer in the file's Properties in Visual Studio, or

  • Adding

      <Content Include=".\xunit.runner.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    

    to your .csproj file, or

  • Adding

      "buildOptions": {
        "copyToOutput": {
          "include": [ "xunit.runner.json" ]
        }
      }
    

    to your project.json file

depending upon your project type.

Finally, in addition to the above, if you're using Visual Studio then make sure that you haven't accidentally clicked the Run Tests In Parallel button, which will cause tests to run in parallel even if you've turned off parallelisation in xunit.runner.json. Microsoft's UI designers have cunningly made this button unlabelled, hard to notice, and about a centimetre away from the "Run All" button in Test Explorer, just to maximise the chance that you'll hit it by mistake and have no idea why your tests are suddenly failing:

Screenshot with the button circled


This is old question but I wanted to write a solution to people searching newly like me :)

Note: I use this method in Dot Net Core WebUI integration tests with xunit version 2.4.1.

Create an empty class named NonParallelCollectionDefinitionClass and then give CollectionDefinition attribute to this class as below. (The important part is DisableParallelization = true setting.)

using Xunit;

namespace WebUI.IntegrationTests.Common
{
    [CollectionDefinition("Non-Parallel Collection", DisableParallelization = true)]
    public class NonParallelCollectionDefinitionClass
    {
    }
}

After then add Collection attribute to the class which you don't want it to run in parallel as below. (The important part is name of collection. It must be same with name used in CollectionDefinition)

namespace WebUI.IntegrationTests.Controllers.Users
{
    [Collection("Non-Parallel Collection")]
    public class ChangePassword : IClassFixture<CustomWebApplicationFactory<Startup>>
    ...

When we do this, firstly other parallel tests run. After that the other tests which has Collection("Non-Parallel Collection") attribute run.