README
¶
BDD Runner
A lightweight, configuration-driven BDD (Behavior-Driven Development) testing engine written in Go. BDD Runner focuses on "zero business coupling, pure configuration-driven" testing with powerful expression evaluation and macro systems.
🎯 Features
- ✅ BDD Standard: Strict Given / When / Then structure (exactly 1 when per scenario)
- ✅ Zero Coupling: HTTP uses only generic fields
status/headers/body/body_raw; WS has no field restrictions - ✅ Expression Evaluation: Powerful expression system based on
exprlibrary, supporting variables, functions, operators - ✅ Macro System: Recursive expansion at configuration stage, no macro concepts at runtime
- ✅ Optional Signing:
http_apisupports optional internal signing (sign.use: api_sign) - ✅ HTML Reports: Clear display of scenarios/steps/duration
- ✅ Control Flow: Supports control flow steps like
if/fail/skip - ✅ Synchronous Waiting: Supports WebSocket push and HTTP callback waiting mechanisms
- ✅ Inline Functions: Built-in functions for time, encoding, hashing, and more
- ✅ Import System: Support for importing external configuration files
- ✅ Concurrent Execution: Multiple scenarios run concurrently for better performance
🚀 Quick Start
Installation
# Clone the repository
git clone https://github.com/magnaflowlabs/bddrunner.git
cd bddrunner
# Build the binary
make build
# Or install directly from GitHub
go install github.com/magnaflowlabs/bddrunner@latest
Version Information
# Show version information
./bddrunner -version
# Show build information
make version
Basic Usage
# Run a test configuration
./bddrunner -config example/basic_example.yaml
# Run with debug mode
./bddrunner -config example/basic_example.yaml -debug
# Run specific scenarios
./bddrunner -config example/macro_example.yaml -scenarios "user_management_test"
📖 Documentation
Configuration Structure
# Import external configuration files
imports:
- macros_presets.yaml
# Global variables
vars:
api_url: "https://api.example.com"
test_user: "testuser"
ws_url: "wss://ws.example.com/websocket"
# Test scenarios
scenarios:
- name: "api_test"
steps:
- given: "set_var"
key: "user_id"
value: "uuid_v4()"
- when: "http_api"
url: api_url + "/users"
method: "POST"
body_obj:
username: test_user
out_var: "result"
- then: "expect"
condition: "result.status == 201"
# Reusable macros
macros:
create_user:
params: ["username", "email"]
steps:
- given: "http_api"
url: api_url + "/users"
method: "POST"
body_obj:
username: "${username}"
email: "${email}"
out_var: "create_result"
Built-in Steps
Setup Steps (Given)
set_var- Set variables (supports bothkeyandnameparameters)http_server- Start HTTP server for callbacksws_connect- Connect to WebSocket
Operation Steps (Given/When)
http_api- HTTP API calls with optional signingws_api- WebSocket API callswait_push- Wait for WebSocket push messageswait_callback- Wait for HTTP callback notifications
Common Steps (Given/When/Then)
sleep_ms- Sleep for millisecondslog- Log messages with variable expansion
Assertion Steps (Then)
expect- Assert conditions with custom error messagesif- Conditional execution with then/else branchesfail- Force scenario failureskip- Skip scenario execution
Expression System
BDD Runner uses the expr library for powerful expression evaluation:
# Variable references (no quotes)
value: "user_name" # References variable user_name
value: "user_age" # References variable user_age
# String literals (with quotes)
value: '"hello world"' # String literal
method: '"POST"' # HTTP method string
# Complex expressions
condition: "user_age > 18 && user_status == 'active'"
message: '"User: " + user_name + " is " + string(user_age) + " years old"'
# Function calls
value: "uuid_v4()" # Generate UUID
value: "now_ms()" # Current timestamp
value: "base64_encode('hello')" # Base64 encoding
Macro System
Macros provide reusable test components with parameter substitution:
macros:
auth_login:
params: ["username", "password"]
steps:
- given: "ws_api"
conn: "ws"
method: '"auth_login"'
params:
username: "${username}"
password: "${password}"
out_var: "login_result"
- given: "expect"
condition: "login_result.code == 200"
# Usage
- call: "auth_login"
args: ['"admin"', '"password123"']
Inline Functions
Built-in functions for common operations:
Time & ID Functions
now_ms()- Current timestamp in millisecondsnow_ts()- Current timestamp in secondsuuid_v4()- Generate UUID v4
String Functions
random_string(length)- Generate random stringbase64_encode(text)- Base64 encodingbase64_decode(text)- Base64 decodingjson_encode(obj)- JSON encodingjson_decode(json)- JSON decoding
Hash Functions
md5_hash(text)- MD5 hashsha256_hash(text)- SHA256 hashhmac_sha256(text, key)- HMAC-SHA256
Passkey Functions (WebAuthn)
passkey_generate_keypair()- Generate Ed25519 keypairpasskey_client_data(challenge, origin, crossOrigin)- Generate client datapasskey_authenticator_data(rp_id)- Generate authenticator datapasskey_signature(challenge, private_key, origin, crossOrigin, rp_id)- Generate signaturepasskey_attestation_object(public_key, auth_data)- Generate attestation object
Import System
Support for importing external configuration files:
imports:
- macros_presets.yaml
- common_variables.yaml
- auth_macros.yaml
Imported files can contain:
- Global variables (later imports override earlier ones)
- Macro definitions (later imports override earlier ones)
- Additional scenarios (all scenarios are merged)
Control Flow
Conditional execution with if steps:
- then: "if"
condition: "user_role == 'admin'"
then_steps:
- then: "set_var"
key: "permissions"
value: '"full_access"'
else_steps:
- then: "set_var"
key: "permissions"
value: '"limited_access"'
📁 Project Structure
bddrunner/
├── main.go # Entry point
├── engine.go # Core engine and execution
├── config.go # Configuration loading and imports
├── context.go # Runtime context and variables
├── registry.go # Step and macro registry
├── steps.go # Built-in steps (set_var, log, sleep_ms)
├── expr.go # Expression evaluation system
├── functions.go # Inline functions implementation
├── macro_expander.go # Macro expansion system
├── transport_http.go # HTTP transport and API signing
├── transport_ws.go # WebSocket transport
├── api_sign.go # API signature implementation
├── control.go # Control flow steps (if, fail, skip)
├── report.go # Test reporting and HTML generation
├── scenario_executor.go # Scenario execution engine
├── docs/ # Documentation
│ ├── ARCHITECTURE.md # System architecture
│ ├── EXPRESSION_SYSTEM.md # Expression evaluation details
│ ├── MACRO_SYSTEM.md # Macro system design
│ └── API_REFERENCE.md # Complete API reference
├── example/ # Example configurations
│ ├── basic_example.yaml
│ ├── macro_example.yaml
│ ├── control_flow_example.yaml
│ ├── inline_functions_example.yaml
│ └── README.md
├── testdata/ # Test configurations
│ ├── basic_expr_test.yaml
│ ├── condition_message_expand_test.yaml
│ ├── function_call_test.yaml
│ ├── test_basic_steps.yaml
│ ├── test_control_flow.yaml
│ ├── test_inline_functions.yaml
│ ├── test_macro_system.yaml
│ ├── ws_api_test.yaml
│ └── README.md
├── Makefile # Build and test automation
├── test.sh # Test runner script
├── .gitignore # Git ignore rules
├── LICENSE # MIT License
├── go.mod # Go module file
├── go.sum # Go dependencies
└── README.md # This file
🧪 Examples
Check the example/ directory for comprehensive examples:
- basic_example.yaml - Basic HTTP and WebSocket testing
- macro_example.yaml - Reusable macro components
- control_flow_example.yaml - Conditional logic and error handling
- inline_functions_example.yaml - Built-in function usage
🔧 Development
Building
# Build binary
make build
# Build for Linux
make build-linux
# Show version information
make version
# Clean build artifacts
make clean
Testing
# Run unit tests
make test
# Run example tests
make test-examples
# Run testdata tests
make test-testdata
# Run all tests
make test-all
# Run comprehensive test suite
./test.sh
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- expr - Expression evaluation library
- godog - BDD framework inspiration
- gorilla/websocket - WebSocket implementation
- Go community for excellent tooling and libraries
Documentation
¶
There is no documentation for this package.