YAML Scenario Format Reference
Complete guide to using YAML format for test scenarios with TinyBDD's File-Based DSL extension.
Overview
YAML provides an alternative to Gherkin for defining test scenarios with structured parameter passing and programmatic generation capabilities.
When to Use YAML
Use YAML when:
- Scenarios are generated by tools or scripts
- Complex parameter values need structured representation
- Tooling integration requires machine-readable format
Use Gherkin when:
- Scenarios are written by humans
- Business readability is priority
- Leveraging existing Gherkin knowledge
Basic Structure
feature: Feature Name
description: Optional feature description
scenarios:
- name: Scenario Name
description: Optional scenario description
tags:
- tag1
- tag2
steps:
- keyword: Given
text: step description
- keyword: When
text: action description
- keyword: Then
text: expectation description
Schema Reference
Feature Object
feature: string (required)
description: string (optional)
tags: string[] (optional)
scenarios: Scenario[] (required)
Example:
feature: Calculator Operations
description: |
Testing basic arithmetic operations
to ensure calculator works correctly
tags:
- calculator
- arithmetic
scenarios:
- # scenario definitions
Scenario Object
name: string (required)
description: string (optional)
tags: string[] (optional)
steps: Step[] (required)
Example:
scenarios:
- name: Add two numbers
description: Verify addition operation
tags:
- smoke
- addition
steps:
- # step definitions
Step Object
keyword: Given|When|Then|And|But (required)
text: string (required)
parameters: object (optional)
Example:
steps:
- keyword: Given
text: a calculator
- keyword: When
text: I add two numbers
parameters:
a: 5
b: 3
- keyword: Then
text: the result should be expected value
parameters:
expected: 8
Parameter Passing
YAML excels at structured parameter passing through the parameters section.
Simple Parameters
steps:
- keyword: When
text: I add two numbers
parameters:
a: 5
b: 3
Maps to:
[DriverMethod("I add two numbers")]
public Task Add(int a, int b)
Complex Values
steps:
- keyword: When
text: I login with credentials
parameters:
username: "john.doe@example.com"
password: "P@ssw0rd with spaces!"
rememberMe: true
Maps to:
[DriverMethod("I login with credentials")]
public Task Login(string username, string password, bool rememberMe)
Mixed Sources
Parameters can come from both pattern placeholders and YAML parameters:
steps:
- keyword: When
text: I process value 123
parameters:
mode: "advanced"
retries: 3
[DriverMethod("I process value {value}")]
public Task Process(int value, string mode, int retries)
{
// value = 123 (from text)
// mode = "advanced" (from parameters)
// retries = 3 (from parameters)
}
Complete Example
feature: User Management
description: Testing user registration and authentication flows
tags:
- user-management
- authentication
scenarios:
- name: Register new user
tags:
- registration
- smoke
steps:
- keyword: Given
text: the registration page is open
- keyword: When
text: I submit registration form
parameters:
username: "newuser123"
email: "newuser@example.com"
password: "SecureP@ssw0rd!"
- keyword: Then
text: account should be created
- keyword: And
text: I should receive confirmation email
parameters:
to: "newuser@example.com"
- name: Login with valid credentials
tags:
- authentication
- smoke
steps:
- keyword: Given
text: a registered user
parameters:
username: "existinguser"
password: "P@ssw0rd123"
- keyword: When
text: I provide credentials
parameters:
username: "existinguser"
password: "P@ssw0rd123"
- keyword: Then
text: I should be authenticated
- keyword: And
text: I should see the dashboard
- name: Login with invalid password
tags:
- authentication
- error-handling
steps:
- keyword: Given
text: a registered user
parameters:
username: "testuser"
password: "correct-password"
- keyword: When
text: I provide wrong password
parameters:
username: "testuser"
password: "wrong-password"
- keyword: Then
text: authentication should fail
- keyword: And
text: I should see error message
parameters:
message: "Invalid credentials"
Usage in Tests
using TinyBDD.Extensions.FileBased;
public class UserManagementTests : FileBasedTestBase<UserManagementDriver>
{
[Fact]
public async Task ExecuteUserManagementScenarios()
{
await ExecuteScenariosAsync(options =>
{
options.AddYamlFiles("Features/UserManagement.yml")
.WithBaseDirectory(Directory.GetCurrentDirectory());
});
}
}
Driver Implementation
public class UserManagementDriver : IApplicationDriver
{
private string? _currentUser;
private bool _isAuthenticated;
[DriverMethod("the registration page is open")]
public Task OpenRegistrationPage()
{
// Implementation
return Task.CompletedTask;
}
[DriverMethod("I submit registration form")]
public async Task SubmitRegistration(
string username,
string email,
string password)
{
// Parameters come from YAML parameters section
await _userService.RegisterAsync(username, email, password);
_currentUser = username;
}
[DriverMethod("account should be created")]
public async Task<bool> AccountExists()
{
var user = await _userService.GetUserAsync(_currentUser!);
return user != null;
}
[DriverMethod("I provide credentials")]
public async Task Login(string username, string password)
{
_isAuthenticated = await _authService.LoginAsync(username, password);
}
[DriverMethod("I should be authenticated")]
public Task<bool> IsAuthenticated()
{
return Task.FromResult(_isAuthenticated);
}
public Task InitializeAsync(CancellationToken ct = default) => Task.CompletedTask;
public Task CleanupAsync(CancellationToken ct = default) => Task.CompletedTask;
}
Parameter Type Conversion
YAML parameters are automatically converted to method parameter types:
| YAML Type | C# Type | Example |
|---|---|---|
| string | string |
username: "john" |
| number | int, long, double, decimal |
count: 42 |
| boolean | bool |
enabled: true |
| null | nullable types | value: null |
Custom Type Conversion
For complex types, use string parameters and convert in the driver method:
parameters:
birthDate: "1990-01-15"
[DriverMethod("I register user")]
public Task RegisterUser(string birthDate)
{
var date = DateTime.Parse(birthDate);
// Use converted value
}
Best Practices
Use Gherkin Keywords Appropriately
# Good: Follows Gherkin semantics
steps:
- keyword: Given
text: initial state
- keyword: When
text: action
- keyword: Then
text: expectation
# Avoid: Misusing keywords
steps:
- keyword: Then
text: set up database # Should be Given
- keyword: Given
text: result is valid # Should be Then
Leverage Parameters for Complex Data
# Good: Complex values in parameters
steps:
- keyword: When
text: I process order
parameters:
customerId: "CUST-12345"
items:
- "ITEM-001"
- "ITEM-002"
shippingAddress: "123 Main St, City, State 12345"
# Avoid: Trying to encode in text
steps:
- keyword: When
text: I process order CUST-12345 with items ITEM-001,ITEM-002 to 123 Main St, City, State 12345
Keep Step Text Readable
# Good: Text describes intent
steps:
- keyword: When
text: I create user account
parameters:
username: "john.doe"
email: "john@example.com"
# Avoid: Parameter names in text
steps:
- keyword: When
text: I create user with username and email
parameters:
username: "john.doe"
email: "john@example.com"
Programmatic Generation
YAML format is ideal for generating scenarios programmatically:
var scenarios = new List<object>();
foreach (var testCase in testCases)
{
scenarios.Add(new
{
name = $"Test {testCase.Name}",
tags = new[] { "generated", testCase.Category },
steps = new[]
{
new { keyword = "Given", text = "system is ready" },
new
{
keyword = "When",
text = "I execute test case",
parameters = new { input = testCase.Input }
},
new
{
keyword = "Then",
text = "output should match expected",
parameters = new { expected = testCase.Expected }
}
}
});
}
var yaml = new
{
feature = "Generated Test Cases",
scenarios = scenarios
};
File.WriteAllText("generated-tests.yml",
new SerializerBuilder().Build().Serialize(yaml));
Validation
YAML files are validated at parse time:
- Required fields: feature, scenarios, name, keyword, text
- Valid keywords: Given, When, Then, And, But
- Structure: Proper nesting and types
Example error:
feature: Test
scenarios:
- name: Invalid Scenario
steps:
- keyword: Invalid # ERROR: Invalid keyword
text: something
Throws: InvalidOperationException: Invalid step keyword 'Invalid'
Limitations
No Scenario Outlines
YAML format does not support Scenario Outline syntax. Use multiple scenarios or programmatic generation:
# Instead of Scenario Outline with Examples:
scenarios:
- name: Add 2 and 3
steps:
- keyword: When
text: I add numbers
parameters: { a: 2, b: 3 }
- keyword: Then
text: result is value
parameters: { expected: 5 }
- name: Add 4 and 5
steps:
- keyword: When
text: I add numbers
parameters: { a: 4, b: 5 }
- keyword: Then
text: result is value
parameters: { expected: 9 }
No Background
Background sections are not supported. Include setup steps in each scenario or use driver initialization.
Related Topics
- File-Based DSL Overview - Main guide
- Gherkin Format Reference - Alternative format
- Samples: API Testing - YAML usage example
Return to: File-Based DSL | Extensions