-
Notifications
You must be signed in to change notification settings - Fork 42
SetUp and TearDown
Page version: 3.x
LightBDD offers ability to setup resources globally for the duration of entire test cycle and tear them down after all tests are executed.
With LightBDD 3.7.0 it is possible to register multiple SetUp and TearDown operations using configuration.ExecutionExtensionsConfiguration()
:
class MyGlobalDependency: IGlobalResourceSetUp
{
public async Task SetUpAsync() { /* ... */}
public async Task TearDownAsync() { /* ... */}
}
class ConfiguredLightBddScopeAttribute : LightBddScopeAttribute
{
protected override void OnConfigure(LightBddConfiguration configuration)
{
configuration.ExecutionExtensionsConfiguration()
.RegisterGlobalSetUp<MyGlobalDependency>()
.RegisterGlobalSetUp("database", SetUpDatabase, TearDownDatabase)
.RegisterGlobalTearDown("cleanup", RunCleanup);
configuration.DependencyContainerConfiguration()
.UseDefault(c =>
{
c.RegisterType<MyGlobalDependency>(InstanceScope.Single);
/*...*/
});
}
private async Task SetUpDatabase() { /* ... */ }
private async Task TearDownDatabase() { /* ... */ }
private async Task RunCleanup() { /* ... */ }
}
In the presented code, multiple SetUp/TearDown activities are registered.
Upon setup, activities are executed in registration order:
-
MyGlobalDependency
will be resolved from the DI (please note it is registered there as singleton) and it'sSetUpAsync()
method will be called first. - If successful, then the
SetUpDatabase()
method will be called.
Upon tear down, activities are called in the reverse order:
-
RunCleanup()
will always be called - then
TearDownDatabase()
will be called, but only ifSetUpDatabase()
was run, - and then
MyGlobalDependency.TearDownAsync()
will be called, but only ifSetUpAsync()
was run.
There are following options available to register global activities:
-
RegisterGlobalSetUp<T>()
for async set up and tear down of resources implementingIGlobalResourceSetUp
, whereTearDownAsync()
is only called when correspondingSetUpAsync()
was run. -
RegisterGlobalSetUp(name, onSetUp, onTearDown)
for set up and tear down (optional) methods, whereonTearDown
method is only called if corresponding setup was run. It is possible to register sync and async activities. -
RegisterGlobalTearDown(name, onTearDown)
for tear down methods (sync and async), where these methods will always be called.
The LightBDDScope described on LightBDD Configuration page offers also OnSetUp()
and OnTearDown()
methods that can be overridden and use for global initialization and cleanup.
Prior to version 3.7.0, this was only available method but since this version it is no longer recommended due to following limitations:
- These methods are not asynchronous thus async operations had to be written in a blocking manner.
- In case multiple resources had to be created/destroyed upon global set up, the clean up logic had to ensure that all the resources are correctly torn down, even if some of them threw exceptions during that operation.
With LightBDD 3.7.0 it is possible to implement IScenarioSetUp
and/or IScenarioTearDown
interface on feature fixture classes to run async setup and async tear down for every scenario defined in this class.
Please note that these methods are called within Runner.Run*()
, thus any resources initialized by OnScenarioSetUpAsync()
won't have initialized state before calling Runner. The following code visualizes it:
// LightBDD.XUnit2 example
public class My_feature : FeatureFixture, IScenarioSetUp, IScenarioTearDown, IDisposable
{
public My_feature(ITestOutputHelper output) : base(output)
{
TestOutput.WriteLine("#ctor");
}
Task IScenarioSetUp.OnScenarioSetUp()
{
TestOutput.WriteLine("#OnScenarioSetUp");
return Task.CompletedTask;
}
Task IScenarioTearDown.OnScenarioTearDown()
{
TestOutput.WriteLine("#OnScenarioTearDown");
return Task.CompletedTask;
}
[Scenario]
public async Task My_scenario()
{
TestOutput.WriteLine("#My_scenario: before Runner.Run()");
try
{
await Runner.RunScenarioAsync(_ => Given_step());
}
finally
{
TestOutput.WriteLine("#My_scenario: after Runner.Run()");
}
}
private Task Given_step()
{
TestOutput.WriteLine("#Given step");
throw new NotImplementedException();
}
void IDisposable.Dispose()
{
TestOutput.WriteLine("#Dispose");
}
}
#ctor
#My_scenario: before Runner.Run()
SCENARIO: My scenario
#OnScenarioSetUp
STEP 1/1: GIVEN step...
#Given step
STEP 1/1: GIVEN step (Failed after 48ms)
#OnScenarioTearDown
#My_scenario: after Runner.Run()
#Dispose
Continue reading: DI Containers
- What Is New
- Quick Start
- Tests Structure and Conventions
- Scenario Steps Definition
- Composite Steps Definition
- SetUp and TearDown
- DI Containers
- Step parameters
- Test Progress Notification
- Generating Reports
- Execution Time Measurement
- Feature Fixture
- Step Comments
- Step Attachments
- Extending Test Behavior
- Test Utilities
- Test Framework Integrations
- LightBDD Configuration
- Visual Studio Extensions
- How to