Executing Code Once Before and After All Tests in xUnit.net

Executing Code Once Before and After All Tests in xUnit.net

21 May 2024 Stephan Petzl Leave a comment Tech-Help

When working with xUnit.net, you may encounter scenarios where you need to run specific setup and teardown code only once for the entire test suite, rather than before and after each individual test. This can be particularly useful for tasks like initializing and disposing of resources that are expensive to create and destroy, such as database connections or web servers.

Using Shared Contexts in xUnit.net

To achieve this in xUnit.net, you can utilize the concept of shared contexts. This involves creating a fixture class that implements the IDisposable interface, a collection definition class, and annotating your test classes to use this collection. Below, we will walk through an example to demonstrate how this is done.

Step-by-Step Guide

  1. Create a Fixture Class

    First, create a class that will handle the setup and teardown logic. This class should implement the IDisposable interface to ensure the teardown logic is executed once all tests are finished.

    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; }
  2. Define a Collection

    Next, create a dummy class to define a collection. This class does not need any code; its purpose is to apply the [CollectionDefinition] attribute and the ICollectionFixture<T> interface.

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

    Finally, annotate your test classes to use the defined collection and inject the fixture through the constructor. This allows the tests to share the fixture instance.

    [Collection("Database collection")]
    public class DatabaseTestClass1
        DatabaseFixture fixture;
        public DatabaseTestClass1(DatabaseFixture fixture)
            this.fixture = fixture;
        // Write tests using fixture.Db to access the SQL Server

    Repeat this step for any other test classes that need to share the same fixture.

Advantages of Shared Contexts

Using shared contexts in xUnit.net provides several benefits:

  • Reduces redundancy by initializing and disposing of resources only once.
  • Improves test performance by avoiding repetitive setup and teardown.
  • Ensures a consistent state across related tests.

Practical Example: Selenium Tests with IIS Express

For instance, if you have Selenium smoke tests that require an IIS Express server, you can use the above method to start and stop IIS Express only once for the entire test suite, rather than for each test. This significantly reduces the overall runtime of your tests.

Enhancing Your Testing Workflow with Repeato

To further streamline your testing process, consider using Repeato, a No-code test automation tool for iOS and Android. Repeato allows you to create, run, and maintain automated tests for your apps efficiently. It leverages computer vision and AI to provide a fast and intuitive testing experience.

With Repeato, you can utilize its no-code interface and test recorder to quickly set up tests, or use the scripting interface for more advanced scenarios. Moreover, Repeato supports testing websites inside an Android emulator or device, with explicit web testing support coming soon.

Explore more about Repeato and how it can help you enhance your testing workflow by visiting our documentation and blog.

For more detailed guides on advanced testing techniques, visit our Advanced Testing Techniques page.

Like this article? there’s more where that came from!