-
Notifications
You must be signed in to change notification settings - Fork 0
Three Tier Specification Model
SpannerSync edited this page Jun 23, 2026
·
1 revision
The three-tier model resolves the dual-audience tension by routing each specification to the test runner best suited to validate it.
| Tag | Audience | Test Runner | Scope |
|---|---|---|---|
@business |
Product owner + AI agent | godog + hand-written fakes | Domain logic, aggregates, domain events |
@integration |
Developer + infrastructure | testcontainers-go + real DB | Adapter persistence round-trips |
@nfr |
Platform engineer |
testing.B benchmarks + testing.F fuzz |
Throughput, concurrency, data volume |
One tag per file — never mix tiers in a single .feature file.
Written in declarative domain language. No UI terms, no SQL, no HTTP paths.
@business
Feature: Order Management
Background:
Given the system contains the following valid product inventory:
| product_id | sku | unit_pence | stock |
| P-1001 | WIDGET-X | 2999 | 50 |
Scenario: Successfully creating an order emits a domain event
Given a customer aggregate initialized with ID "CUST-998"
When the customer submits a create order command with the following payload:
"""json
{"customer_id":"CUST-998","items":[{"product_id":"P-1001","quantity":2}]}
"""
Then the order aggregate should be successfully created
And an "order.created" domain event is published to the broker
And the total order value in pence should be 5998Rules:
- DataTables define Go struct field names and types (column header → CamelCase field)
- DocStrings define the exact JSON command payload schema
- Every
Thenasserts a domain event AND a mathematical invariant - Monetary values in
int64pence — neverfloat64or£symbols
Validates that the infrastructure adapter correctly persists and retrieves domain objects using a real database.
@integration
Feature: Order Persistence
Background:
Given a clean PostgreSQL database is available
Scenario: Saved order is retrievable by ID
Given an order with ID "ORD-100" for customer "CUST-500" and total 2999 pence
When the order is saved to the repository
Then finding order "ORD-100" returns the same order with total 2999 penceZero Trust Pillar 3: Every scenario runs inside a SQL transaction unconditionally rolled back after completion — regardless of pass or fail. No inter-scenario data contamination is possible.
Captures non-functional requirements as executable specifications.
@nfr
Feature: Order Throughput and Resilience
Scenario: Order creation throughput meets SLA
Given a pre-seeded inventory of 1000 products
When 500 concurrent order creation requests are submitted
Then all requests complete within 2 seconds
And zero orders are lost or duplicatedRun benchmarks:
go test -bench=. ./tests/...Run fuzz:
go test -fuzz=FuzzCreateOrder -fuzztime=30s ./tests/...