Choosing a test framework
BDTest does not replace your test runner. It runs inside it. An adapter package connects BDTest to the runner's test identity, lifecycle and skip/inconclusive exceptions through framework-native composition or an optional base class.
| Adapter | Base class | Package |
|---|---|---|
| TUnit (recommended) | TUnitBDTestBase<TContext> | BDTest.TUnit |
| NUnit | NUnitBDTestBase<TContext> | BDTest.NUnit |
| xUnit v3 | XUnitBDTestBase<TContext> | BDTest.xUnit |
| MSTest | MSTestBDTestBase<TContext> | BDTest.MSTest |
| Standalone | BDTestBase, BDTestBuilder | BDTest |
All adapter base classes take a context type with the constraint where TContext : class. The default factory needs a public parameterless constructor; custom factories support constructor dependencies. There are no non-generic adapter base classes. Use an empty context class if you do not need state.
If your test class already has another base class, use NUnit composition registration, TUnit composition registration, xUnit composition registration, or MSTest composition registration. The core composition host also supports manual lifecycle integration for other runners.
What an adapter does
Adapter base classes derive from AbstractContextBDTestBase<TContext>. All four adapters also provide framework-native composition. Each adapter:
- supplies a unique execution ID for each test from the framework's test context, so context and output stay isolated in parallel runs,
- declares the framework's success, skip and inconclusive exceptions in one
FrameworkOutcomeMap, registered on its own frozen assembly run, - marks each test as started and completed, and removes its context afterwards,
- maps a whole-scenario skip onto the runner's skip mechanism.
Feature comparison
| TUnit | NUnit | xUnit v3 | MSTest | |
|---|---|---|---|---|
| Execution ID | TestContext.Current.Id | Test.ID + repeat count | TestContext.Current.Test.UniqueID | class and data-row display name + execution suffix |
| Success exception | — | SuccessException (Assert.Pass) | — | — |
| Skip exception | SkipTestException (Skip.Test) | IgnoreException (Assert.Ignore) | SkipException (Assert.Skip) | — |
| Inconclusive exception | InconclusiveTestException | InconclusiveException | — | AssertInconclusiveException |
| Whole-scenario skip | SkipTestException | Assert.Ignore | Assert.Skip | Assert.Inconclusive |
| Runs with | dotnet run / dotnet test (Microsoft.Testing.Platform) | dotnet test | dotnet run (Microsoft.Testing.Platform); dotnet test with the VSTest fallback | dotnet test |
The examples in this documentation use TUnit. Swap the base class, test attributes and assertions for your framework.
Not using one of these frameworks? See Custom adapters.
For an explicit run, register the adapter's OutcomeMap on BDTestOptions before
calling BDTestRun.Start(options). Both classification and skip notifications use
that run's frozen configuration. The shared conformance suite
checks each adapter's BDTest statuses and actual runner outcomes, including the
frameworks' explicit differences.