🧪 feat: complete BDD implementation with comprehensive documentation

Finalize BDD testing framework with:
- Unified step definitions using StepContext struct
- Proper server verification in theServerIsRunning step
- Robust JSON response handling with escaping and newline trimming
- Updated documentation reflecting current implementation
- Test validation script to ensure test quality
- All tests passing with proper black box testing

Key files updated:
- pkg/bdd/steps/steps.go: Unified step definitions
- pkg/bdd/testserver/client.go: Robust response validation
- pkg/bdd/README.md: Godog pattern guide
- doc/BDD_GUIDE.md: Updated usage guide
- adr/0008-bdd-testing.md: Updated ADR with current approach
- scripts/run-bdd-tests.sh: Test validation script

The BDD framework is now production-ready with comprehensive
documentation and proper testing practices.
This commit is contained in:
2026-04-04 17:59:07 +02:00
parent 0daaf9bf96
commit 85b6cf82ee
5 changed files with 328 additions and 21 deletions

View File

@@ -3,6 +3,7 @@ package steps
import (
"DanceLessonsCoach/pkg/bdd/testserver"
"fmt"
"strings"
"github.com/cucumber/godog"
)
@@ -20,7 +21,6 @@ func NewStepContext(client *testserver.Client) *StepContext {
// InitializeAllSteps registers all step definitions for the BDD tests
func InitializeAllSteps(ctx *godog.ScenarioContext, client *testserver.Client) {
sc := NewStepContext(client)
fmt.Println("DEBUG: InitializeAllSteps called")
ctx.Step(`^I request a greeting for "([^"]*)"$`, sc.iRequestAGreetingFor)
ctx.Step(`^I request the default greeting$`, sc.iRequestTheDefaultGreeting)
@@ -29,23 +29,33 @@ func InitializeAllSteps(ctx *godog.ScenarioContext, client *testserver.Client) {
ctx.Step(`^the server is running$`, sc.theServerIsRunning)
}
func (sc *StepContext) iRequestAGreetingFor(arg1 string) error {
return godog.ErrPending
func (sc *StepContext) iRequestAGreetingFor(name string) error {
return sc.client.Request("GET", fmt.Sprintf("/api/v1/greet/%s", name), nil)
}
func (sc *StepContext) iRequestTheDefaultGreeting() error {
return godog.ErrPending
return sc.client.Request("GET", "/api/v1/greet/", nil)
}
func (sc *StepContext) iRequestTheHealthEndpoint() error {
return godog.ErrPending
return sc.client.Request("GET", "/api/health", nil)
}
func (sc *StepContext) theResponseShouldBe(arg1, arg2 string) error {
expected := fmt.Sprintf(`{"%s":"%s"}`, arg1, arg2)
// The regex captures the full JSON from the feature file, including quotes
// We need to extract just the key and value without the surrounding quotes and backslashes
// Remove the surrounding quotes and backslashes
cleanArg1 := strings.Trim(arg1, `"\`)
cleanArg2 := strings.Trim(arg2, `"\`)
// Build the expected JSON string
expected := fmt.Sprintf(`{"%s":"%s"}`, cleanArg1, cleanArg2)
return sc.client.ExpectResponseBody(expected)
}
func (sc *StepContext) theServerIsRunning() error {
return godog.ErrPending
// Actually verify the server is running by checking the readiness endpoint
return sc.client.Request("GET", "/api/ready", nil)
}