🧪 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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
@@ -46,9 +47,21 @@ func (c *Client) ExpectResponseBody(expected string) error {
|
||||
}
|
||||
|
||||
actual := string(c.lastBody)
|
||||
// Trim trailing newline if present (common in JSON responses)
|
||||
actual = strings.TrimSuffix(actual, "\n")
|
||||
|
||||
if actual != expected {
|
||||
return fmt.Errorf("expected response body %q, got %q", expected, actual)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper methods for debugging
|
||||
func (c *Client) GetLastResponse() *http.Response {
|
||||
return c.lastResp
|
||||
}
|
||||
|
||||
func (c *Client) GetLastBody() []byte {
|
||||
return c.lastBody
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user