Skip to content
Development
Skill

/nw-test-design-mandates

Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion,

From plugin
nwave
591200 skills34 agents27 commands
Install
$ npx -y skills add nWave-ai/nWave --skill nw-test-design-mandates --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/nw-test-design-mandates

Context preview

The summary Claude sees to decide when to auto-load this skill.

Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion,

SKILL.md

nw-test-design-mandates.SKILL.md
name: nw-test-design-mandates
description: Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion, layer-dependent PBT mode, two-tier acceptance, example-based sad paths)
user-invocable: false
disable-model-invocation: true

Acceptance Test Design Mandates

Four mandates enforced during peer review. All must pass before handoff to software-crafter.

LANGUAGE CONVENTION FRAME (read FIRST — overrides all examples below)

**Code examples in this skill use Python syntax for illustration only.** They are NOT prescriptive about target language. nWave is language-agnostic per the "genericity and agnosticism" mandate (2026-05-24).

**Before applying mandates**, detect the target project's language from manifest files: `package.json` → TypeScript/JS; `Cargo.toml` → Rust; `go.mod` → Go; `pyproject.toml`/`setup.py`/`Pipfile` → Python; `pom.xml`/`build.gradle` → Java/Kotlin; `*.csproj`/`*.fsproj` → C#/F#; `Gemfile` → Ruby; `Package.swift` → Swift.

**When the target language is NOT Python**: adapt EVERY code example — replace Python imports (`from pytest_bdd import ...`, `from hypothesis import ...`), type hints, class/function syntax, test-framework idioms, directory conventions (`tests/` vs `test/` vs `__tests__/`) with target equivalents. Project conventions ALWAYS WIN over skill examples — if the user's repo has 50 TS files and zero Python files, mandates apply via TypeScript test framework, never Python pytest.

**Empirical anchor**: 5 of 5 Python code blocks in this skill, zero TS/Go/Rust — root-cause for language-leak per F-SKILL-EXAMPLES-LANGUAGE-LEAK. Connects [[feedback_language_adapter_plugin_architecture_2026_05_24]] (genericity mandate).

Mandate 1: Hexagonal Boundary Enforcement

Tests invoke through driving ports (entry points), never internal components.

Driving Ports (Test Through These)

Application services/orchestrators | API controllers/CLI handlers | Message consumers/event handlers | Public API facade classes

Not Entry Points (Never Test Directly)

Internal validators, parsers, formatters | Domain entities/value objects | Repository implementations | Internal service components

Correct Pattern

# Invoke through system entry point (driving port)
from myapp.orchestrator import AppOrchestrator

def when_user_performs_action(self):
    orchestrator = AppOrchestrator()
    self.result = orchestrator.perform_action(
        context=self.context
    )

Violation Pattern

# Invoking internal component directly
from myapp.validator import InputValidator  # INTERNAL

def when_user_validates_input(self):
    validator = InputValidator()  # WRONG BOUNDARY
    self.result = validator.validate(self.input)

Testing internal components creates Testing Theater: tests pass but users cannot access feature through actual entry point. Integration wiring bugs remain hidden.

Mandate 2: Business Language Abstraction

Step methods speak business language, abstract all technical details.

Three Abstraction Layers

**Layer 1 - Gherkin**: Pure business language, all stakeholders. Domain terms from ubiquitous language | Zero technical jargon | Describe WHAT user does, not HOW system does it

Scenario: Customer places order for available product
  Given customer has items in shopping cart
  When customer submits order
  Then order is confirmed
  And customer receives confirmation email

**Layer 2 - Step Methods**: Business service delegation. Method names use domain terms | Delegate to business service layer (OrderService, not HTTP client) | Assert business outcomes (order.is_confirmed()), not technical state (status_code == 201)

def when_customer_submits_order(self):
    self.result = self.order_service.place_order(
        customer=self.customer, items=self.cart_items
    )

def then_order_is_confirmed(self):
    assert self.result.is_confirmed()
    assert self.result.has_order_number()

**Layer 3 - Business Services**: Production services handle technical implementation. HTTP calls, DB transactions, SMTP hidden inside service layer.

Test Smell Indicators

`requests.post()` in step method | `db.execute()` in step method | `assert response.status_code` | Technical terms in Gherkin

Mandate 3: User Journey Completeness

Tests validate complete user journeys with business value, not isolated technical operations.

Complete Journey Structure

Every scenario includes: **User trigger** (Given/When) | **Business logic** (When - system processes rules) | **Observable outcome** (Then - user sees result) | **Business value** (Then - value delivered)

Correct Example

Scenario: Customer successfully completes purchase
  Given customer has selected products worth $150
  And customer has valid payment method
  When customer submits order
  Then order is confirmed with order number
  And customer receives email confirmation
  And order appears in customer's order history

Violation Example

Scenario: Order validator accepts valid order data
  Given valid order JSON exists
  When validator.validate() is called
  Then validation passes
# Tests isolated validation, not user journey

Scenario Name Test

Does name express user value or technical operation? "Customer completes purchase" = correct. "Validator accepts JSON" = violation.

Walking Skeleton Strategy

Balance user-centric E2E integration tests with focused boundary tests.

Walking Skeletons (2-5 per feature)

Trace thin vertical slice delivering observable user value E2E | Each answers: "Can a user accomplish this goal and see the result?" | Express simplest complete user journey | Validate system delivers demo-able stakeholder value | Touch all layers as consequence of journey, not as design g

Read more
Ships withnwave

AI agents that guide you from idea to working code, with human judgment at every gate. nWave runs inside Claude Code. It breaks feature delivery into seven waves (discover, diverge, discuss, design, devops, distill, deliver).

Get the whole plugin