Skip to main content

Specification Pattern

The Specification pattern provides a streamlined way to write executable specifications without the ceremony of Given/When/Then. Inspired by MSpec (Machine.Specifications), it fits precise business policies as well as technical components and APIs when direct rules communicate more clearly than a narrative.

What Is the Specification Pattern?​

While the BDD pattern excels at describing workflows, not every claim benefits from the Given/When/Then structure. A product manager may want the exact shipping-rate examples without reading a checkout journey; the same directness helps when testing a math library, validation utility, or API contract:

// BDD for a simple calculation — more ceremony than value
Feature: Calculator
Scenario: Adding two numbers
Given the first number is 3
And the second number is 5
When the numbers are added
Then the result should be 8

The Specification pattern cuts straight to the point:

Specification: Calculator
Rule: Adding 3 and 5 produces 8
Rule: Multiplying by zero always returns zero
Rule: Dividing by zero throws an error

Each Rule is one independently verifiable claim about the system. It can use multiple related assertions to prove that claim. There are no step keywords: the specification title, rules, and examples provide the detail.

Conceptual Vocabulary

The examples on this page use the LiveDoc conceptual vocabulary — Specification, Rule, RuleOutline. Unlike the BDD pattern which borrows from Gherkin, the Specification pattern is a LiveDoc concept inspired by MSpec. Each SDK implements it using its platform's native idioms:

  • TypeScript/Vitest: Function calls — specification(), rule(), ruleOutline()
  • C#/xUnit: Classes and attributes — SpecificationTest base class, [Rule], [RuleOutline]

See SDK Support for links to the actual code syntax.

The Structure​

The Specification pattern uses a simple two-level hierarchy:

Specification​

A Specification is the top-level container — analogous to a Feature in BDD. It groups related rules under a descriptive title:

Specification: Email Validator
@validation @input-handling
Rules governing email address validation across the platform.

Like Features, Specifications support:

  • Tags for filtering and categorization (@validation, @unit)
  • Descriptions for additional context
  • Skip and Only modifiers for test control

Rule​

A Rule is a focused fact about the system that the test verifies. It's analogous to a Scenario, but without the Given/When/Then step structure:

Specification: Email Validator

Rule: Accepts addresses with standard format (user@domain.com)

Rule: Rejects addresses without an @ symbol

Rule: Rejects addresses with multiple @ symbols

Rule: Accepts addresses with subdomains (user@mail.domain.com)

Rule: Trims whitespace before validation

Rules contain direct test code — setup, action, and assertion all in one block. This makes them extremely compact and readable as a list of behaviors.

RuleOutline​

For data-driven specifications, RuleOutline works just like ScenarioOutline — a template with an Examples table:

Specification: Email Validator

RuleOutline: Email '<email>' has validity '<valid>'
Examples:
| email | valid |
| user@example.com | true |
| invalid | false |
| user@.com | false |
| a@b.co | true |
| user @domain.com | false |

Each row becomes a separate test in the documentation output, making all variations visible at a glance. Learn more in Data-Driven Tests.

When to Use the Specification Pattern​

The Specification pattern is the right choice when:

  • The claim is a precise rule — A product owner may inspect shipping, eligibility, or discount examples alongside a workflow Feature
  • Tests are self-contained — A single rule captures setup, action, and assertion naturally
  • You're testing many variations — A list of rules reads better than a list of scenarios with repeated Given/When/Then
  • The component is technical — APIs, utilities, algorithms, data transformers
  • Directness beats narrative — The behavior is clear without the Given/When/Then framing

Examples of Good Specification Use​

ComponentWhy Specification Fits
Shipping and pricing policiesExact input/output examples make thresholds and exceptions inspectable
Validation utilitiesMany rules, each a simple input → output check
Math/algorithm logicDirect assertions on computed results
Parser behaviorMany edge cases, each a one-line rule
Configuration optionsEach option has a clear expected default/behavior
Error handlingEach error condition is a standalone assertion
Type coercionMany input/output pairs, perfect for RuleOutline

How It Differs from BDD​

The fundamental difference is structure vs. directness:

AspectBDD PatternSpecification Pattern
Organizing conceptFeature → Scenario → StepsSpecification → Rule
Step keywordsGiven, When, Then, And, ButNone
Setup and assertionSeparated into distinct stepsCombined in a single block
Reader's focusFollowing a workflowInspecting precise rules and examples
Data-driven variantScenarioOutlineRuleOutline
Best read asA user story with examplesA list of facts about the system
Typical test countFewer, more detailed scenariosMany, more concise rules

Side-by-Side Comparison​

Here's the same behavior expressed in both patterns:

BDD approach:

Feature: Password Strength Validator
Scenario: Weak password (too short)
Given a password 'abc'
When the password strength is checked
Then the result should be 'weak'

Scenario: Strong password
Given a password 'MyS3cure!Pass'
When the password strength is checked
Then the result should be 'strong'

Specification approach:

Specification: Password Strength Validator
Rule: Passwords shorter than 8 characters are rated 'weak'
Rule: Passwords with mixed case, numbers, and symbols are rated 'strong'
Rule: Passwords with only lowercase letters are rated 'medium'
Rule: Empty passwords are rated 'weak'

Neither is "better" — they serve different purposes. The BDD version tells a story; the Specification version provides a concise rule reference. A product owner can read either when it documents the behavior they care about.

Decision Guide​

Use this flowchart to choose the right pattern:

What kind of claim is this?
├── A workflow where preconditions, action, and outcome tell the story
│ └── Use Feature / Scenario
└── A focused rule or exact input/output contract
└── Use Specification / Rule or RuleOutline
Mix Freely

Most projects benefit from using both patterns. A common convention:

  • BDD for workflows that benefit from Given/When/Then
  • Specification for precise business policies and technical contracts

LiveDoc supports both in the same project. Keep related Features and Specifications together under the business capability in the Viewer; see Test Organization.

The Specification Pattern as Living Documentation​

Just like BDD, the Specification pattern produces living documentation. The key difference is in the shape of that documentation:

  • BDD documentation reads like a narrative: "Given this context, when the user does X, then Y happens."
  • Specification documentation reads like a reference sheet: "Here are the exact rules for this capability."

Both are valuable. A reader can follow an Orders checkout Feature and inspect its nearby Shipping rates Specification for boundary cases without switching to a separate technical catalogue.

SDK Support​

Both LiveDoc SDKs fully support the Specification pattern:

  • TypeScript/Vitest: Uses function calls — specification(), rule(), ruleOutline(). See Your First Spec.
  • C#/xUnit: Uses classes and methods — inherit from SpecificationTest, define rule methods. See Your First Spec.

The concepts are identical across both SDKs. Only the syntax differs.

Recap​

  • The Specification pattern is a compact alternative to BDD, inspired by MSpec.
  • Specification groups related rules; Rule is a direct assertion without step ceremony.
  • RuleOutline provides data-driven testing with Examples tables.
  • Use Specification for precise business or technical rules and tests with many variations.
  • Use BDD when a Given/When/Then narrative adds clarity.
  • Both patterns produce living documentation and belong together under their capability.

Next Steps​