Xunit.Net: Global Setup + Teardown

xUnit.net: Global setup + teardown?

As far as I know, xUnit does not have a global initialization/teardown extension point. However, it is easy to create one. Just create a base test class that implements IDisposable and do your initialization in the constructor and your teardown in the IDisposable.Dispose method. This would look like this:

public abstract class TestsBase : IDisposable
{
protected TestsBase()
{
// Do "global" initialization here; Called before every test method.
}

public void Dispose()
{
// Do "global" teardown here; Called after every test method.
}
}

public class DummyTests : TestsBase
{
// Add test methods
}

However, the base class setup and teardown code will be executed for each call. This might not be what you want, as it is not very efficient. A more optimized version would use the IClassFixture<T> interface to ensure that the global initialization/teardown functionality is only called once. For this version, you don't extends a base class from your test class but implement the IClassFixture<T> interface where T refers to your fixture class:

using Xunit;

public class TestsFixture : IDisposable
{
public TestsFixture ()
{
// Do "global" initialization here; Only called once.
}

public void Dispose()
{
// Do "global" teardown here; Only called once.
}
}

public class DummyTests : IClassFixture<TestsFixture>
{
public DummyTests(TestsFixture data)
{
}
}

This will result in the constructor of TestsFixture only being run once
for every class under test. It thus depends on what you want exactly to choose between the two methods.

How to perform global setup/teardown in xUnit and run tests in parallel?

NUnit supports this scenario. For global setup, create a class in one of your root namespaces and add the [SetupFixture] attribute to it. Then add a [OneTimeSetUp] method to that class. This method will get run once for all tests in that namespace and in child namespaces. This allows you to have additional namespace specific onetime setups.

[SetUpFixture]
public class MySetUpClass
{
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
// ...
}

[OneTimeTearDown]
public void RunAfterAnyTests()
{
// ...
}
}

Then to run your tests in parallel, add the [Parallelizable] attribute at the assembly level with the ParallelScope.All. If you have tests that should not be run in parallel with others, you can use the NonParallelizable attribute at lower levels.

[assembly: Parallelizable(ParallelScope.All)]

Running test methods in parallel in NUnit is supported in NUnit 3.7 and later. Prior to that, it only supported running test classes in parallel. I would recommend starting any project with the most recent version of NUnit to take advantages of bug fixes, new features and improvements.

run initialisation and teardown code once while outputting in the constructor and destructor

The documentation says that you can add a parameter of type ITestOutputHelper to the constructor of the test class. I don't see anything that says you can add it as a parameter to the constructor of a test fixture class...

It wouldn't make sense for this output to go via ITestOutputHelper because the whole point of that mechanism is to allow the output to be associated with a specific test. Your setup/teardown is global, not per-test.

You'll need to find another way to output those diagnostics.

Await Tasks in Test Setup Code in xUnit.net?

xUnit has an IAsyncLifetime interface for async setup/teardown. The methods you need to implement are Task InitializeAsync() and Task DisposeAsync().

InitializeAsync is called immediately after the class has been created, before it is used.

DisposeAsync is called just before IDisposable.Dispose if the class also implements IDisposable.

e.g.

public class MyTestFixture : IAsyncLifetime
{
private string someState;

public async Task InitializeAsync()
{
await Task.Run(() => someState = "Hello");
}

public Task DisposeAsync()
{
return Task.CompletedTask;
}

[Fact]
public void TestFoo()
{
Assert.Equal("Hello", someState);
}
}

Run code once before and after ALL tests in xUnit.net


As of Nov 2015 xUnit 2 is out, so there is a canonical way to share features between tests. It is documented here.

Basically you'll need to create a class doing the fixture:

    public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");

// ... initialize data in the test database ...
}

public void Dispose()
{
// ... clean up test data from the database ...
}

public SqlConnection Db { get; private set; }
}

A dummy class bearing the CollectionDefinition attribute.
This class allows Xunit to create a test collection, and will use the given fixture for all test classes of the collection.

    [CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}

Then you need to add the collection name over all your test classes.
The test classes can receive the fixture through the constructor.

    [Collection("Database collection")]
public class DatabaseTestClass1
{
DatabaseFixture fixture;

public DatabaseTestClass1(DatabaseFixture fixture)
{
this.fixture = fixture;
}
}

It's a bit more verbose than MsTests AssemblyInitialize since you have to declare on each test class which test collection it belongs, but it's also more modulable (and with MsTests you still need to put a TestClass on your classes)

Note: the samples have been taken from the documentation.



Related Topics



Leave a reply



Submit