BDDfy's behavior is controlled through the static Configurator class. Everything from step scanning to reporting is pluggable.
using TestStack.BDDfy.Configuration;
// All configuration is done via static properties:
Configurator.Processors // Per-scenario pipeline
Configurator.BatchProcessors // End-of-run reporters
Configurator.Scanners // Step discovery
Configurator.IdGenerator // Unique key generation
Configurator.StepExecutor // Step execution strategy
Configurator.Humanizer // Method name → readable text
Configurator.FluentScannerFactory // Fluent scanner creation
Configurator.StepTitleFactory // Step title generation
Configurator.CultureInfo // Culture for formatting
Configurator.AsyncVoidSupportEnabled // async void step support (default: true)Processors run for each scenario in order of their ProcessType:
// Disable console output
Configurator.Processors.ConsoleReport.Disable();
// Add a custom processor
Configurator.Processors.Add(() => new MyCustomProcessor());Built-in processors (in execution order):
- TestRunner — executes the scenario steps
- ConsoleReporter — prints to console
- ExceptionProcessor — handles/rethrows exceptions
- StoryCache — stores results for batch reporters
- Disposer — disposes the test object if
IDisposable
Configurator.Processors.TestRunner.Disable();
Configurator.Processors.ConsoleReport.Disable();
Configurator.Processors.StoryCache.Disable();Run once after all scenarios complete (typically reporters):
Configurator.BatchProcessors.HtmlReport.Enable();
Configurator.BatchProcessors.HtmlMetroReport.Disable();
Configurator.BatchProcessors.MarkDownReport.Enable();
Configurator.BatchProcessors.DiagnosticsReport.Enable();
// Add custom batch processor
Configurator.BatchProcessors.Add(new MyBatchProcessor());Control how BDDfy discovers steps in your test classes:
// Disable attribute-based scanning
Configurator.Scanners.ExecutableAttributeScanner.Disable();
// Disable method-name scanning
Configurator.Scanners.DefaultMethodNameStepScanner.Disable();
// Add a custom step scanner
Configurator.Scanners.Add(() => new MyCustomStepScanner());Replace how story metadata is discovered:
Configurator.Scanners.StoryMetadataScanner = () => new MyCustomMetadataScanner();The humanizer converts method names into readable titles:
// Replace with a custom humanizer
Configurator.Humanizer = new MyHumanizer();
public class MyHumanizer : IHumanizer
{
public string Humanize(string name)
{
// Custom logic to convert PascalCase/underscored names to text
return name.Replace("_", " ");
}
}Override how individual steps are executed:
Configurator.StepExecutor = new MyStepExecutor();
public class MyStepExecutor : IStepExecutor
{
public void Execute(Step step, object testObject)
{
// Add logging, timing, retry logic, etc.
Console.WriteLine($"Executing: {step.Title}");
step.Execute(testObject);
}
}Customize how step titles are generated from expressions:
Configurator.StepTitleFactory = new MyStepTitleFactory();Set the culture used for formatting values in reports:
Configurator.CultureInfo = new CultureInfo("en-US");BDDfy can detect and await async void step methods. Disable if it causes issues:
Configurator.AsyncVoidSupportEnabled = false;Configure BDDfy before any tests run. With xUnit, use a module initializer or assembly fixture:
using System.Runtime.CompilerServices;
using TestStack.BDDfy.Configuration;
public static class BDDfySetup
{
[ModuleInitializer]
public static void Initialize()
{
Configurator.BatchProcessors.HtmlReport.Disable();
Configurator.BatchProcessors.MarkDownReport.Enable();
}
}With NUnit, use [SetUpFixture]:
[SetUpFixture]
public class BDDfySetup
{
[OneTimeSetUp]
public void Setup()
{
Configurator.BatchProcessors.HtmlMetroReport.Enable();
}
}