Skip to content

Three Tier Specification Model

SpannerSync edited this page Jun 23, 2026 · 1 revision

Three-Tier Specification Model

The three-tier model resolves the dual-audience tension by routing each specification to the test runner best suited to validate it.


Tier Overview

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.


@business Tier

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 5998

Rules:

  • DataTables define Go struct field names and types (column header → CamelCase field)
  • DocStrings define the exact JSON command payload schema
  • Every Then asserts a domain event AND a mathematical invariant
  • Monetary values in int64 pence — never float64 or £ symbols

@integration Tier

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 pence

Zero 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.


@nfr Tier

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 duplicated

Run benchmarks:

go test -bench=. ./tests/...

Run fuzz:

go test -fuzz=FuzzCreateOrder -fuzztime=30s ./tests/...

Clone this wiki locally