I have a set of xunit.net tests that need to share state. Hopefully, I would like these tests to run in parallel. So I would want the runner to do:
When reading the the xunit doc, it says that to share state between test classes, I need to define a 'collection fixture' and then but all my test classes into that new collection (ex: [Collection("Database collection")]
). But when, I put my test class in the same fixture, they don't run in parallel anymore so it beats the purpose :(
Is there a built-in way to do what I want in XUnit?
My fallback will be to put my shared state into a static class.
Running unit tests in parallel is a new feature in xUnit.net version 2. There are two essential motivations that drove us to not only enable parallelization, but also for it to be a feature that's enabled by default: As unit testing has become more prevalent, so too have the number of unit tests.
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 the same collection then it will run sequentially.
MSTest is concerned, the biggest difference between xUnit and the other two test frameworks (NUnit and MSTest) is that xUnit is much more extensible when compared to NUnit and MSTest. The [Fact] attribute is used instead of the [Test] attribute.
For every test, xUnit creates a new instance of the test class, which implies that the codes in the class constructor are run for each test. Oftentimes, it is desirable for unit test classes to share a test context because it can be expensive to create and clean up test contexts.
You can extend xUnit using the AssemblyFixture example from the samples pasted below to create a fixture which can the accesses by tests while running in parallel.
Using this method the fixture is created before the tests and then injected into the tests which reference it. I use this to create a user which is then shared for that specific set run.
There is also a nuget package xunit.assemblyfixture
:
using System;
using Xunit;
// The custom test framework enables the support
[assembly: TestFramework("AssemblyFixtureExample.XunitExtensions.XunitTestFrameworkWithAssemblyFixture", "AssemblyFixtureExample")]
// Add one of these for every fixture classes for the assembly.
// Just like other fixtures, you can implement IDisposable and it'll
// get cleaned up at the end of the test run.
[assembly: AssemblyFixture(typeof(MyAssemblyFixture))]
public class Sample1
{
MyAssemblyFixture fixture;
// Fixtures are injectable into the test classes, just like with class and collection fixtures
public Sample1(MyAssemblyFixture fixture)
{
this.fixture = fixture;
}
[Fact]
public void EnsureSingleton()
{
Assert.Equal(1, MyAssemblyFixture.InstantiationCount);
}
}
public class Sample2
{
MyAssemblyFixture fixture;
public Sample2(MyAssemblyFixture fixture)
{
this.fixture = fixture;
}
[Fact]
public void EnsureSingleton()
{
Assert.Equal(1, MyAssemblyFixture.InstantiationCount);
}
}
public class MyAssemblyFixture : IDisposable
{
public static int InstantiationCount;
public MyAssemblyFixture()
{
InstantiationCount++;
}
public void Dispose()
{
// Uncomment this and it will surface as an assembly cleanup failure
//throw new DivideByZeroException();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With