Skip to content

Binding Feature Testing as an alternative to specflow #1

@wendellmva

Description

@wendellmva

🎯 Goal

Document the overall setup and structure of the repository so contributors understand:

  • How the library is organized
  • How the reporting logic works
  • How the self-validating tests assert the coverage output

This will serve as an onboarding reference.


🟢 Project Overview

The solution has three main parts:

1️⃣ Library (LowlandTech.Testing.Features)

  • Provides the core test framework:
    • [Scenario], [Then], [TaskId], [UseCaseId], [NodeId]
    • WhenTestingFor<T>
    • WhenUsingDatabase<TContext>
  • Allows users to write BDD-style tests in pure C# with rich metadata.

2️⃣ Reporter (AssemblyCoverageExtensions)

  • Contains extension methods on Assembly:
    • GenerateCoverageReport(outputPath, reportTitle)
      • Generates Markdown coverage
    • GenerateCoverageReportAsync(...)
  • Formats:
    • Scenario codes
    • Titles
    • Given/When/Then text
    • UAC codes
    • Tags (NodeId, TaskId, UseCaseId)

3️⃣ Tests (LowlandTech.Testing.Features.Tests)

  • Contains meta tests to validate that the coverage generator itself works.
  • Example test classes:
    • ScenarioWithCodeAndTitle
    • ScenarioWithNodeId
    • ScenarioWithTaskId
    • ScenarioWithUseCaseId
  • A special test (CoverageReportTests) generates coverage.md and asserts it contains all expected strings.

🟢 Setup Instructions

1️⃣ Build the library

From the solution root:

dotnet build

This compiles LowlandTech.Testing.Features.


2️⃣ Write feature tests

Add test classes like:

[Scenario(
    "VCHIP-4001-SC001",
    "Simple scenario title",
    "Given a simple context",
    "When an action occurs",
    "Then an outcome is expected")]
[TaskId("VCHIP-4001-TK001")]
[UseCaseId("VCHIP-4001-UC001")]
[NodeId("vy.test.example")]
public class ScenarioWithAllMetadata : WhenTestingFor<int>
{
    protected override int For() => 0;
    protected override void When() { }

    [Fact]
    [Then("Outcome happened", "VCHIP-4001-UAC001")]
    public void ShouldBeTrue() { 0.ShouldBe(0); }
}

This is what drives the generated report.


3️⃣ Generate the coverage report

Either:

  • From the standalone CLI tool:
coverage-tool ./bin/Debug/net8.0/LowlandTech.Testing.Features.Tests.dll ./COVERAGE.md "My Project Feature Coverage"

or:

  • Programmatically in tests:
var assembly = Assembly.GetExecutingAssembly();
assembly.GenerateCoverageReport("coverage.md", "My Project Coverage");

4️⃣ Validate the output in tests

In CoverageReportTests:

[Fact]
public void ItGeneratesCoverageReportContainingAllMetadata()
{
    var assembly = Assembly.GetExecutingAssembly();
    assembly.GenerateCoverageReport("coverage.md", "Test Coverage");
    var report = File.ReadAllText("coverage.md");

    report.ShouldContain("VCHIP-4001-SC001");
    report.ShouldContain("VCHIP-4001-UAC001");
    report.ShouldContain("VCHIP-4001-TK001");
    report.ShouldContain("VCHIP-4001-UC001");
    report.ShouldContain("vy.test.example");
}

✅ This proves that all metadata appears as expected.


🟢 Directory Structure

/src/
  LowlandTech.Testing.Features/
    - Attributes/
    - Base/
    - Reporter/
      AssemblyCoverageExtensions.cs
  LowlandTech.Testing.Features.Tests/
    ScenarioWithCodeAndTitle.cs
    ScenarioWithNodeId.cs
    ScenarioWithTaskId.cs
    ScenarioWithUseCaseId.cs
    CoverageReportTests.cs
/tools/
  LowlandTech.CoverageTool/
    Program.cs

🟢 Future Enhancements

  • Add HTML export in GenerateCoverageReport
  • Support .feature file generation for SpecFlow compatibility
  • Allow optional YAML frontmatter for metadata
  • Snapshot testing the entire report content

Please reference this issue whenever creating new scenarios or extending the reporting functionality.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions