Class TestBase
- Namespace
- TinyBDD
- Assembly
- TinyBDD.dll
Minimal, framework-agnostic base class for TinyBDD tests that wires the
ambient ScenarioContext and offers convenience Given helpers.
public abstract class TestBase
- Inheritance
-
TestBase
- Derived
- Inherited Members
Examples
xUnit (call CleanUp() in teardown):
using TinyBDD;
using TinyBDD.Xunit;
using Xunit;
public sealed class MyXunitBase : TestBase, IAsyncLifetime
{
protected override IBddReporter Reporter { get; } = new XunitReporter();
public Task InitializeAsync()
{
Ambient.Current.Value = Bdd.CreateContext(this, featureName: "Sample Feature");
return Task.CompletedTask;
}
public Task DisposeAsync()
{
CleanUp(); // writes Gherkin summary, clears Ambient.Current
return Task.CompletedTask;
}
}
public sealed class SampleTests : MyXunitBase
{
[Fact]
public async Task Demo()
{
await Given("a number", () => 2)
.When("double it", x => x * 2)
.Then("equals 4", v => v == 4);
Scenario.AssertPassed();
}
}
MSTest (use [TestInitialize]/[TestCleanup]):
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public sealed class MyMsTestBase : TestBase
{
protected override IBddReporter Reporter { get; } = new MsTestReporter(TestContext!);
public TestContext? TestContext { get; set; }
[TestInitialize]
public void SetUp()
=> Ambient.Current.Value = Bdd.CreateContext(this, featureName: "Feature");
[TestCleanup]
public void TearDown() => CleanUp();
}
NUnit (use [SetUp]/[TearDown]):
using NUnit.Framework;
public sealed class MyNUnitBase : TestBase
{
protected override IBddReporter Reporter { get; } = new NUnitReporter();
[SetUp]
public void SetUp()
=> Ambient.Current.Value = Bdd.CreateContext(this, featureName: "Feature");
[TearDown]
public void TearDown() => CleanUp();
}
Remarks
TestBase centralizes TinyBDD test wiring for any unit-test framework (xUnit, NUnit, MSTest). It expects a derived type (or framework-specific base) to set Current to a live ScenarioContext before a test runs, and to call CleanUp() afterward (typically in teardown).
All Given overloads delegate to Flow which in turn forwards to
Bdd using the current ambient context. If the ambient context is not set,
an InvalidOperationException is thrown when invoking any step.
The base also exposes From() to start chains against an explicit ScenarioContext—useful when composing helper methods that construct sub-chains without relying on global ambient state.
Properties
BackgroundExecuted
Gets a value indicating whether background steps have been executed.
protected bool BackgroundExecuted { get; }
Property Value
BackgroundState
Gets or sets the background state captured after ExecuteBackgroundAsync(CancellationToken) completes.
protected object? BackgroundState { get; }
Property Value
Remarks
This property is populated by ExecuteBackgroundAsync(CancellationToken) after running the background steps configured in ConfigureBackground().
FeatureSetupExecuted
Gets a value indicating whether feature setup has been executed.
protected bool FeatureSetupExecuted { get; set; }
Property Value
FeatureState
Gets or sets the feature state captured after ExecuteFeatureSetupAsync(CancellationToken) completes.
protected object? FeatureState { get; set; }
Property Value
Remarks
This property is populated by ExecuteFeatureSetupAsync(CancellationToken) after running the feature setup steps configured in ConfigureFeatureSetup(). Feature state is shared across all scenarios in the test class.
Reporter
The reporter used to emit scenario output (e.g., Gherkin-style summaries) at cleanup. Framework-specific base classes should provide an appropriate implementation.
protected abstract IBddReporter Reporter { get; }
Property Value
Scenario
The current ScenarioContext for the running test, sourced from Current. This is non-null during a properly initialized test.
protected ScenarioContext Scenario { get; }
Property Value
Methods
CleanUp()
Writes a concise Gherkin-style run summary (via GherkinFormatter) if a ScenarioContext is present, then clears Current.
protected void CleanUp()
Remarks
Call this from your framework teardown hook (e.g., xUnit DisposeAsync,
MSTest [TestCleanup], or NUnit [TearDown]). It is safe to call even
if no scenario was started (no-op aside from clearing ambient state).
ConfigureBackground()
Override to configure background steps that run before each scenario.
protected virtual ScenarioChain<object>? ConfigureBackground()
Returns
- ScenarioChain<object>
A ScenarioChain<T> representing the background steps, or null if no background is needed.
Examples
protected override ScenarioChain<object>? ConfigureBackground()
{
return Given("a database connection", () => new DbConnection())
.And("test data seeded", conn => { SeedData(conn); return conn; });
}
Remarks
Background steps are executed once before each test method by calling ExecuteBackgroundAsync(CancellationToken). The final value from the chain is stored in BackgroundState and can be accessed via GivenBackground<T>().
Override this method in your test class to define shared setup steps.
The background chain should not call AssertPassed(); that is
handled automatically by ExecuteBackgroundAsync(CancellationToken).
ConfigureFeatureSetup()
Override to configure feature-level setup steps that run once before any scenarios.
protected virtual ScenarioChain<object>? ConfigureFeatureSetup()
Returns
- ScenarioChain<object>
A ScenarioChain<T> representing the feature setup steps, or null if no feature setup is needed.
Examples
protected override ScenarioChain<object>? ConfigureFeatureSetup()
{
return Given("test server started", () => new TestServer())
.And("database seeded", server => { server.SeedData(); return server; });
}
Remarks
Feature setup steps are executed once before any test method runs in the test class. The final value from the chain is stored in FeatureState and can be accessed from all scenarios.
This is useful for expensive setup operations that can be shared across multiple scenarios, such as creating a test database connection, initializing a web server, or loading test data.
ConfigureFeatureTeardown()
Override to configure feature-level teardown steps that run once after all scenarios complete.
protected virtual ScenarioChain<object>? ConfigureFeatureTeardown()
Returns
- ScenarioChain<object>
A ScenarioChain<T> representing the feature teardown steps, or null if no feature teardown is needed.
Examples
protected override ScenarioChain<object>? ConfigureFeatureTeardown()
{
if (FeatureState is TestServer server)
{
return Given("cleanup server", () => server)
.And("dispose", s => { s.Dispose(); return s; });
}
return null;
}
Remarks
Feature teardown steps are executed once after all test methods in the test class complete. Use this to clean up expensive resources initialized in ConfigureFeatureSetup().
ExecuteBackgroundAsync(CancellationToken)
Executes the background steps configured in ConfigureBackground().
protected Task ExecuteBackgroundAsync(CancellationToken ct = default)
Parameters
ctCancellationTokenOptional cancellation token.
Returns
- Task
A task representing the asynchronous operation.
Remarks
Call this method from your test framework's initialization hook
(e.g., [TestInitialize], [SetUp], or InitializeAsync)
after setting up the ambient context.
The final value from the background chain is captured in BackgroundState.
ExecuteFeatureSetupAsync(CancellationToken)
Executes the feature setup steps configured in ConfigureFeatureSetup().
protected Task ExecuteFeatureSetupAsync(CancellationToken ct = default)
Parameters
ctCancellationTokenOptional cancellation token.
Returns
- Task
A task representing the asynchronous operation.
Remarks
Call this method from your test framework's one-time initialization hook
(e.g., xUnit IAsyncLifetime.InitializeAsync with static state,
MSTest [ClassInitialize], or NUnit [OneTimeSetUp]).
The final value from the feature setup chain is captured in FeatureState.
ExecuteFeatureTeardownAsync(CancellationToken)
Executes the feature teardown steps configured in ConfigureFeatureTeardown().
protected Task ExecuteFeatureTeardownAsync(CancellationToken ct = default)
Parameters
ctCancellationTokenOptional cancellation token.
Returns
- Task
A task representing the asynchronous operation.
Remarks
Call this method from your test framework's one-time cleanup hook
(e.g., xUnit IAsyncLifetime.DisposeAsync with static state,
MSTest [ClassCleanup], or NUnit [OneTimeTearDown]).
From()
Creates a helper bound to the current ambient Scenario for starting chains without relying on static Flow methods in downstream helpers.
protected FromContext From()
Returns
- FromContext
A FromContext tied to Scenario.
From(ScenarioContext)
Creates a helper for starting chains from an explicit ScenarioContext.
protected FromContext From(ScenarioContext ctx)
Parameters
ctxScenarioContextThe scenario context to use for subsequent calls.
Returns
- FromContext
A FromContext bound to
ctx.
GivenBackground<T>()
Starts a Given step that continues from the background state.
protected ScenarioChain<T> GivenBackground<T>() where T : class
Returns
- ScenarioChain<T>
A ScenarioChain<T> starting with the background state.
Type Parameters
TThe expected type of the background state.
Examples
[Test]
public async Task TestWithBackground()
{
await GivenBackground<DbConnection>()
.When("querying users", conn => conn.Query<User>("SELECT * FROM Users"))
.Then("users exist", users => users.Any())
.AssertPassed();
}
Exceptions
- InvalidOperationException
Thrown if background steps have not been executed or the state is null.
GivenBackground<T>(string)
Starts a Given step that continues from the background state with a custom title.
protected ScenarioChain<T> GivenBackground<T>(string title) where T : class
Parameters
titlestringA custom title for the Given step.
Returns
- ScenarioChain<T>
A ScenarioChain<T> starting with the background state.
Type Parameters
TThe expected type of the background state.
GivenFeature<T>()
Starts a Given step that continues from the feature state.
protected ScenarioChain<T> GivenFeature<T>() where T : class
Returns
- ScenarioChain<T>
A ScenarioChain<T> starting with the feature state.
Type Parameters
TThe expected type of the feature state.
Examples
[Test]
public async Task TestWithFeature()
{
await GivenFeature<TestServer>()
.When("sending request", server => server.Get("/api/users"))
.Then("response is ok", response => response.StatusCode == 200)
.AssertPassed();
}
Exceptions
- InvalidOperationException
Thrown if feature setup has not been executed or the state is null.
GivenFeature<T>(string)
Starts a Given step that continues from the feature state with a custom title.
protected ScenarioChain<T> GivenFeature<T>(string title) where T : class
Parameters
titlestringA custom title for the Given step.
Returns
- ScenarioChain<T>
A ScenarioChain<T> starting with the feature state.
Type Parameters
TThe expected type of the feature state.
Given<T>(Func<CancellationToken, Task<T>>)
Starts a token-aware Given step with a default title and asynchronous setup.
protected ScenarioChain<T> Given<T>(Func<CancellationToken, Task<T>> setup)
Parameters
setupFunc<CancellationToken, Task<T>>
Returns
Type Parameters
T
Given<T>(Func<CancellationToken, ValueTask<T>>)
Starts a token-aware Given step with a default title and ValueTask<TResult> setup.
protected ScenarioChain<T> Given<T>(Func<CancellationToken, ValueTask<T>> setup)
Parameters
setupFunc<CancellationToken, ValueTask<T>>
Returns
Type Parameters
T
Given<T>(Func<Task<T>>)
Starts a Given step with a default title and asynchronous setup.
protected ScenarioChain<T> Given<T>(Func<Task<T>> setup)
Parameters
Returns
Type Parameters
T
Given<T>(Func<ValueTask<T>>)
Starts a Given step with a default title and ValueTask<TResult> setup.
protected ScenarioChain<T> Given<T>(Func<ValueTask<T>> setup)
Parameters
Returns
Type Parameters
T
Given<T>(Func<T>)
Starts a Given step with a default title and synchronous setup.
protected ScenarioChain<T> Given<T>(Func<T> setup)
Parameters
setupFunc<T>
Returns
Type Parameters
T
Given<T>(string, Func<CancellationToken, Task<T>>)
Starts a token-aware Given step with an explicit title and asynchronous setup.
protected ScenarioChain<T> Given<T>(string title, Func<CancellationToken, Task<T>> setup)
Parameters
titlestringsetupFunc<CancellationToken, Task<T>>
Returns
Type Parameters
T
Given<T>(string, Func<CancellationToken, ValueTask<T>>)
Starts a token-aware Given step with an explicit title and ValueTask<TResult> setup.
protected ScenarioChain<T> Given<T>(string title, Func<CancellationToken, ValueTask<T>> setup)
Parameters
titlestringsetupFunc<CancellationToken, ValueTask<T>>
Returns
Type Parameters
T
Given<T>(string, Func<Task<T>>)
Starts a Given step with an explicit title and asynchronous setup.
protected ScenarioChain<T> Given<T>(string title, Func<Task<T>> setup)
Parameters
Returns
Type Parameters
T
Remarks
Use this overload when the initial value requires async I/O.
Given<T>(string, Func<ValueTask<T>>)
Starts a Given step with an explicit title and ValueTask<TResult> setup.
protected ScenarioChain<T> Given<T>(string title, Func<ValueTask<T>> setup)
Parameters
Returns
Type Parameters
T
Given<T>(string, Func<T>)
Starts a Given step with an explicit title and synchronous setup.
protected ScenarioChain<T> Given<T>(string title, Func<T> setup)
Parameters
Returns
- ScenarioChain<T>
A ScenarioChain<T> for chaining
When/Then.
Type Parameters
TType produced by the setup function.