TestDataDefinitionFramework.Core
1.0.0
See the version list below for details.
dotnet add package TestDataDefinitionFramework.Core --version 1.0.0
NuGet\Install-Package TestDataDefinitionFramework.Core -Version 1.0.0
<PackageReference Include="TestDataDefinitionFramework.Core" Version="1.0.0" />
<PackageVersion Include="TestDataDefinitionFramework.Core" Version="1.0.0" />
<PackageReference Include="TestDataDefinitionFramework.Core" />
paket add TestDataDefinitionFramework.Core --version 1.0.0
#r "nuget: TestDataDefinitionFramework.Core, 1.0.0"
#addin nuget:?package=TestDataDefinitionFramework.Core&version=1.0.0
#tool nuget:?package=TestDataDefinitionFramework.Core&version=1.0.0
TestDataDefinitionFramework
TestDataDefinitionFramework (or TDDF for short) is a library that abstracts the setup of test data from the implementation of data backing stores, so that the same test code can be run against both an in-memory/fake repository or a "real" repository using only pre-compiler conditionals to switch between the two.
An immediate design limitation is that this method will ONLY work when you are using "dumb data stores", so if you are running multi-table SQL queries or stored procedures, then this is not the library for you!
However, if your interactions with your data layer are usually that of "store this entity in this table", "query this entity from this table" then read on!
The Use Case
Ordinarily when writing integration tests (for example using SpecFlow) you will decide; "is this going to run against an in-memory fake, or against the "real" repository".
There are pros and cons to deciding on one: "in-memory" is fast and can run on the build server, but doesn't thoroughly test your data provider layer. Using "real" repositories more thoroughly tests your code layers as it proves the integration of your code with the chosen data storage engine, but is slower and requires connectivity to a running instance of your data storage engine of choice (e.g. a MongoDB or SQL instance).
Ideally it's nice to have both options, but a lot times this leads to a duplication of the integration test code - in SpecFlow terms the "step definitions" can look very different when you want to "setup" a MongoDB than when you only want to setup an in-memory context and pass that to an interceptor/fake repository.
The idea of TDDF is that by setting your test data against the TestDataStore you can then use that same data in an in-memory repository as easily as enabling a "real" backing store and the TDDF plugins will take care of actually standing up the "real" data resource.
Getting Started
- Clone the source code repository and build, or install packages via NuGet.
- Add a reference to "TestDataDefinitionFramework.Core" into your "integration tests" project (for example your SpecFlow/NUnit project).
- Choose which backing stores plugins you want to use (e.g. TestDataDefinitionFramework.MongoDB)
- Wire-up the code:
- Configure and Initialize (do this before your tests run), e.g. in SpecFlow
[BeforeTestRun]
public static async Task Initialize()
{
var mongoBackingStore = new MongoBackingStore("ExampleSutDB");
TestDataStore.AddRepository<SummaryItem>(cfg =>
{
cfg.WithName(SummaryCollection.Name);
#if UseRealProvider
cfg.WithBackingStore(mongoBackingStore);
#endif
});
await TestDataStore.InitializeAllAsync();
}
- Use the TestDataStore for your setting up your test data, e.g. in SpecFlow
[Given(@"the summaries repository returns '(.*)'")]
public void GivenTheSummariesRepositoryReturns(IReadOnlyList<string> items)
{
TestDataStore.Repository<SummaryItem>(SummaryCollection.Name).Items = items.Select(i => new SummaryItem {Name = i}).ToArray();
}
- Add your in-memory repository fakes (for when running in-memory mode):
public class WebTestFixture : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.UseEnvironment("Testing");
builder.ConfigureTestServices(services =>
{
#if !UseRealProvider
services.AddTransient<ISummariesRepository, InMemorySummariesRepository>();
#endif
});
}
}
- Implement your in-memory repository:
public class InMemorySummariesRepository : ISummariesRepository
{
public Task<IReadOnlyList<string>> GetAllAsync()
{
var result = TestDataStore.Repository<SummaryItem>(SummaryCollection.Name)
.Items?.Select(i => i.Name).ToArray()
?? Array.Empty<string>();
return Task.FromResult((IReadOnlyList<string>) result);
}
}
- Commit the test data before calling the SUT (the best way to acheive this in SpecFlow is to trigger before the "When" block)
[BeforeScenarioBlock]
public async Task Commit()
{
if (_scenarioContext.CurrentScenarioBlock == ScenarioBlock.When)
{
await TestDataStore.CommitAllAsync();
}
}
Now you can run your tests against an in-memory fake, or against a "real" repository by simply setting or unsetting a pre-compiler conditional called "UseRealProvider".
Notes
- See the ExampleTests project for a working version of the above
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net5.0
NuGet packages (3)
Showing the top 3 NuGet packages that depend on TestDataDefinitionFramework.Core:
Package | Downloads |
---|---|
TestDataDefinitionFramework.MongoDB
MongoDB backing store extension for TestDataDefinitionFramework |
|
TestDataDefinitionFramework.Sql
Sql backing store extension for TestDataDefinitionFramework |
|
TestDataDefinitionFramework.Redis
Redis backing store extension for TestDataDefinitionFramework |
GitHub repositories
This package is not used by any popular GitHub repositories.