Attributes
LiveDoc provides custom attributes that integrate with xUnit's test discovery.
Class-level attributes define containers (features, specifications). Method-level
attributes define test cases that inherit from xUnit's [Fact] or [Theory].
using SweDevTools.LiveDoc.xUnit;
[Feature("Shopping Cart", Description = "Business rules for cart checkout.")]
public class CartTests : FeatureTest
{
public CartTests(ITestOutputHelper output) : base(output) { }
[Scenario("Free shipping for large orders")]
public void Free_shipping() { /* ... */ }
[ScenarioOutline("Calculate tax for different regions")]
[Example("AU", 10.0)]
[Example("US", 0.0)]
public void Tax_calculation(string region, double rate) { /* ... */ }
}
Class-Level Attributes
[Feature]
Marks a test class as a BDD Feature. The class must inherit from FeatureTest.
[AttributeUsage(AttributeTargets.Class)]
public class FeatureAttribute : Attribute
Parameters
name(optional):string— The feature title. If omitted, the class name is used with underscores converted to spaces.Description(named, optional):string— Multi-line description displayed in formatted output.
// Explicit title
[Feature("User Registration")]
public class RegistrationTests : FeatureTest { }
// Auto-derived title: "Registration Tests"
[Feature]
public class Registration_Tests : FeatureTest { }
// With description
[Feature("Order Processing", Description = @"
End-to-end order processing including validation,
payment capture, and fulfillment dispatch.")]
public class OrderTests : FeatureTest { }
[Specification]
Marks a test class as an MSpec Specification. The class must inherit from SpecificationTest.
[AttributeUsage(AttributeTargets.Class)]
public class SpecificationAttribute : Attribute
Parameters
title(optional):string— The specification title. If omitted, the class name is used.Description(named, optional):string— Description displayed in formatted output.
[Specification("Email Validation", Description = @"
Rules for validating email formats including
international domains and special characters.")]
public class EmailSpec : SpecificationTest { }
Method-Level Attributes
[Scenario]
Marks a method as a single BDD scenario. Inherits from xUnit's FactAttribute, so xUnit discovers it automatically.
public class ScenarioAttribute : FactAttribute
Parameters
testMethodName(optional):string— Display name in Test Explorer. Defaults to the method name via[CallerMemberName].Description(named, optional):string— Additional context shown in formatted output.
// Auto-named from method: "User logs in successfully"
[Scenario]
public void User_logs_in_successfully() { }
// Explicit display name
[Scenario("User logs in with valid credentials")]
public void User_logs_in_successfully() { }
// With description
[Scenario(Description = "Tests the complete login flow for registered users")]
public void User_logs_in_successfully() { }
// Both title and description
[Scenario("Login flow", Description = "Happy path for registered users")]
public void User_logs_in_successfully() { }
Because [Scenario] inherits from [Fact], xUnit discovers and runs these methods with no custom test runner. They appear in Test Explorer alongside regular [Fact] tests.
[ScenarioOutline]
Marks a method as a data-driven BDD scenario. Inherits from xUnit's TheoryAttribute. Requires one or more [Example] attributes.
public class ScenarioOutlineAttribute : TheoryAttribute
Parameters
testMethodName(optional):string— Display name. Defaults to method name.Description(named, optional):string— Description for formatted output.
[ScenarioOutline]
[Example("Alice", true)]
[Example("Unknown", false)]
public void User_authentication(string username, bool expected) { }
[ScenarioOutline("Validate shipping rates")]
[Example("AU", 100, "Free")]
[Example("NZ", 100, "International")]
public void Shipping_rates(string country, decimal total, string type) { }
[ScenarioOutline(Description = "Covers all regional tax rules")]
[Example("AU", 10.0)]
[Example("US", 0.0)]
public void Tax_rates(string region, double rate) { }
[Rule]
Marks a method as a single MSpec rule. Inherits from xUnit's FactAttribute. Used in classes inheriting SpecificationTest.
public class RuleAttribute : FactAttribute
Parameters
description(optional):string— The rule title with embedded values. If omitted, the method name is used.testMethodName(optional):string— Internal method name for CallerMemberName.Description(named, optional):string— Additional description shown in output.
// Title with embedded values
[Rule("Adding '5' and '3' returns '8'")]
public void Addition() { }
// Auto-named from method
[Rule]
public void Adding_positive_numbers_increases_the_total() { }
// With named parameters
[Rule("Subtracting <b:3> from <a:10> returns <result:7>")]
public void Subtraction() { }
[RuleOutline]
Marks a method as a data-driven MSpec rule. Inherits from xUnit's TheoryAttribute. Requires [Example] attributes.
public class RuleOutlineAttribute : TheoryAttribute
Parameters
description(optional):string— Rule title with<placeholder>segments for display.testMethodName(optional):string— Internal method name.Description(named, optional):string— Additional description.
[RuleOutline("Adding '<a>' and '<b>' returns '<result>'")]
[Example(1, 2, 3)]
[Example(5, 5, 10)]
[Example(-1, 1, 0)]
public void Addition_examples(int a, int b, int result) { }
[Example]
Provides data rows for [ScenarioOutline] and [RuleOutline]. Inherits from xUnit's DataAttribute. See [Example] Attribute for full details.
[Example("Australia", 100.00, "Free")]
Attribute Inheritance from xUnit
LiveDoc attributes extend xUnit's native attributes, ensuring full compatibility with all xUnit tooling:
| LiveDoc Attribute | xUnit Base | Discovery |
|---|---|---|
[Scenario] | FactAttribute | Single test case |
[ScenarioOutline] | TheoryAttribute | One test case per [Example] |
[Rule] | FactAttribute | Single test case |
[RuleOutline] | TheoryAttribute | One test case per [Example] |
[Example] | DataAttribute | Data source for Theory |
This means:
- Tests appear in Test Explorer without custom adapters
- All xUnit runners (
dotnet test, VS, Rider) work automatically [Scenario]tests can useSkip = "reason"just like[Fact][ScenarioOutline]tests support xUnit's theory data pipeline
// Skip a scenario (inherited from FactAttribute)
[Scenario(Skip = "Pending implementation")]
public void Upcoming_feature() { }
Description Property
All attributes accept a Description named property. Descriptions appear in the formatted test output and LiveDoc Viewer, providing valuable context:
[Feature("Checkout Flow", Description = @"
Business rules for the complete checkout process
including cart validation, payment, and confirmation.")]
public class CheckoutTests : FeatureTest
{
public CheckoutTests(ITestOutputHelper output) : base(output) { }
[Scenario("Apply coupon code", Description = @"
Validates that valid coupon codes reduce the total
and expired codes show an appropriate message.")]
public void Apply_coupon() { /* ... */ }
}
Output:
Feature: Checkout Flow
Business rules for the complete checkout process
including cart validation, payment, and confirmation.
Scenario: Apply coupon code
Validates that valid coupon codes reduce the total
and expired codes show an appropriate message.
Given ...
When ...
Then ...
Always provide Description on [Feature] and [Specification] attributes. It costs nothing and makes the living documentation significantly more useful.
Method Name Conventions
Automatic title derivation
When no explicit title is provided, the method name is converted:
- Underscores (
_) become spaces - Example:
User_logs_in_successfully→ "User logs in successfully"
_ALLCAPS placeholder segments
In [ScenarioOutline] and [RuleOutline], _ALLCAPS segments in method names become <placeholder> markers matched to method parameters:
[RuleOutline]
[Example(10, 2, 5)]
[Example(100, 10, 10)]
public void Dividing_A_by_B_returns_RESULT(int a, int b, int result)
{
Assert.Equal(result, a / b);
}
// Output: "Dividing '10' by '2' returns '5'"
Matching rules:
_Amatches parametera,A, or_a(case-insensitive)- Unmatched ALLCAPS segments remain as literal text
- This is an alternative to providing an explicit title with
<param>placeholders
See Also
FeatureTest— base class for BDD testsSpecificationTest— base class for MSpec tests[Example]— data rows for outlines- Step Methods —
Given(),When(),Then(),And(),But() - Best Practices — attribute usage patterns