IsolatedTests is a .NET library that enables test class isolation in your test suites using a simple attribute-based approach. It supports .NET 6, .NET 7, .NET 8 and .NET 9.
- Isolated Test Classes – Ensure test classes are isolated from each other to avoid shared state issues.
- Simple Initialization – Minimal setup using a
[ModuleInitializer]. - Seamless Integration – Use
[IsolatedTest]to mark classes that should be isolated.
Add the IsolatedTests package to your test project:
dotnet add package IsolatedTests- Make sure your test project targets
.NET 6+. - Make sure to disable Optimization or specifically JIT inlining so that test methods are not potentially inlined.
Initialize IsolatedTests once at module startup using the [ModuleInitializer] attribute:
using System.Runtime.CompilerServices;
using IsolatedTests;
public static class TestSetup {
[ModuleInitializer]
internal static void ModuleInitializer() {
if(TestIsolator.ModuleInitializer()) {
// Do your other one time initializations here...
// ex: dockerContainer.start();
}
// Code here will run for each assembly load triggered by [IsolatedTest]
// ex: MyTestContext.parseFiles();
}
}This ensures that isolation is injected before any tests run.
To isolate a test class, simply decorate it with the [IsolatedTest] attribute:
using IsolatedTests.Attribute;
public class MySharedState {
private static MySharedState? _instance;
internal static MySharedState Instance => _instance ??= new MySharedState();
internal bool IsInitialized {
get;
set;
}
}
[TestClass]
[IsolatedTest]
public class MyIsolatedTest1 {
[TestMethod]
public void Test1() {
lock (MySharedState.Instance) {
Assert.IsFalse(MySharedState.Instance.IsInitialized);
MySharedState.Instance.IsInitialized = true;
}
}
}
[TestClass]
[IsolatedTest]
public class MyIsolatedTest2 {
[TestMethod]
public async Task Test2() {
await Task.Delay(1000)
.ContinueWith(t => {
lock (MySharedState.Instance) {
Assert.IsFalse(MySharedState.Instance.IsInitialized);
MySharedState.Instance.IsInitialized = true;
}
});
}
}Only test classes marked with [IsolatedTest] will be isolated. Regular test classes continue to run as usual.
IsolatedTests is powered by UnsafeCLR (thus the non-support for net6.0 ARM64), a runtime method manipulation library.
Here’s what happens under the hood:
-
UnsafeCLRis used to dynamically edit the implementation of your test methods at runtime. This allowsIsolatedTeststo intercept calls to test methods. -
Once a test method is intercepted,
IsolatedTestsloads the test assembly (if not previously done for this class) into a completely separate, isolated assembly context. -
The intercepted method call is then re-routed to execute inside this new context, providing full isolation from other tests.
This approach ensures that static state, global configuration, or other test-related side effects do not bleed between test classes.
- .NET 6 (ARM64 is not supported)
- .NET 7
- .NET 8
- .NET 9
- .NET 10
See LICENSE
Pull requests are welcome! For major changes, please open an issue first to discuss what you'd like to change.
Found an issue or have a feature request? Open an issue.