Solutech Engineering

Living Documentation with BDD Features

Living Documentation with BDD Features: A Comprehensive Guide

Version 2.0 — Definitive Standard


Table of Contents

  1. Introduction
  2. Core Philosophy
  3. The Feature Structure
  4. Features vs Rules vs Scenarios
  5. Writing Features
  6. Writing Rules
  7. Writing Scenarios
  8. Using Tags
  9. Organizing Features into Modules
  10. Language and Vocabulary
  11. Common Anti-Patterns
  12. Case Study: Cart Management
  13. Complete Example
  14. Quality Checklist

1. Introduction

1.1 What Is Living Documentation?

Living documentation is documentation that:

  • Evolves with the system it describes
  • Remains accurate because it's verified continuously
  • Serves multiple audiences: business stakeholders, developers, testers, and product owners
  • Uses business language that everyone can understand
  • Drives implementation rather than documenting it after the fact

1.2 Why BDD Features?

BDD (Behavior-Driven Development) features using Gherkin syntax provide:

  • Shared understanding across technical and non-technical team members
  • Executable specifications that can be automated
  • Clear traceability from business requirement to implementation
  • Natural language documentation accessible to all stakeholders
  • Single source of truth for what the system does

1.3 Who Should Read This?

  • Product owners defining requirements
  • Business analysts documenting capabilities
  • Domain experts contributing knowledge
  • Developers implementing features
  • QA engineers writing tests
  • Anyone responsible for maintaining system documentation

2. Core Philosophy

2.1 Three Fundamental Principles

Features describe capabilities
Rules describe constraints
Scenarios describe examples

This hierarchy must be preserved. Violating it leads to feature sprawl, duplication, and confusion.

2.2 Business-First Thinking

Every statement in a feature file must answer: "What business value does this provide?"

If the answer involves technology, implementation, or how the system is structured internally, it doesn't belong in the feature file.

Feature files document what the business needs, not how the system delivers it.

2.3 Who Are We Writing For?

Feature files serve multiple audiences with one shared language:

  • Business stakeholders who define requirements
  • Product owners who prioritize work
  • Domain experts who understand the business rules
  • Developers who implement the capability
  • Testers who verify the behavior
  • Future team members who need to understand what the system does

If any of these audiences cannot understand a feature file, it's not written correctly.

The key insight: we write features in language that everyone can understand, not in language that requires technical knowledge.


3. The Feature Structure

3.1 Mandatory Components

Every feature file must contain:

Feature: <capability name>
  In order to <business value>
  As a <primary role>
  I need to <capability>

  Rule: <constraint description>
    
    Scenario: The one where <something happens>
      Given <context>
      When <action>
      Then <outcome>

3.2 Gherkin 6 Syntax

This standard uses Gherkin 6 which introduces:

  • Rule: keyword for grouping related scenarios
  • Better semantic organization
  • Clearer separation of concerns

3.3 Component Hierarchy

Feature (1)
├── Intent Block (1, mandatory)
└── Rules (1..n)
    └── Scenarios (1..n)
        ├── Given steps (0..n)
        ├── When step (1, exactly)
        └── Then steps (1..n)

4. Features vs Rules vs Scenarios

4.1 What Is a Feature?

A Feature is a business capability that delivers value independently.

The Feature Test:
Can a user clearly say: "I can do this now"?

If removing it would remove a meaningful business capability → it's a feature.

Valid Features:

  • Submit an order
  • Record a customer visit
  • Collect a payment
  • Plan a daily route
  • Approve a credit request
  • Perform stock taking

Not Features:

  • User can submit orders (permission)
  • Orders require approval above limit (rule)
  • Customer must be in route plan (constraint)
  • Validate order totals (technical concern)

4.2 What Is a Rule?

A Rule is a constraint that must hold when a feature action occurs.

The Rule Test:
Would this be checked at the moment the user performs this action?

If yes → it belongs as a rule in that feature.

Rules typically represent:

  • Business policies
  • Permissions and authorization
  • Configuration settings
  • Approval thresholds
  • Assignment constraints (customers, products, territories)
  • Regulatory requirements
  • Validation criteria

Example Rules:

Rule: Orders may only be placed for customers in the active route plan
Rule: Credit orders must satisfy credit and approval policies
Rule: Product prices are determined automatically based on business configuration
Rule: Only authorized users may place orders

4.3 What Is a Scenario?

A Scenario is a concrete example demonstrating a rule.

Scenarios are:

  • Examples, not exhaustive test cases
  • Specific, not abstract or generic
  • Independent of other scenarios
  • Focused on one observable outcome

Example:

Scenario: The one where the customer is in the active route plan
  Given customer "Acme Store" is in today's active route plan
  When the order is placed
  Then the order is submitted successfully

5. Writing Features

5.1 The Feature Intent Block

Every feature begins with a mandatory intent block:

Feature: <capability name>
  In order to <business value>
  As a <primary role>
  I need to <capability>

Rules for intent blocks:

  1. Use business language only — no technical terms
  2. State value first — why this matters
  3. Identify one primary role — who needs this
  4. Describe the capability — what they can do
  5. No conditions — save those for rules
  6. No implementation details — focus on business intent

Good Examples:

Feature: Submit an order
  In order to record customer purchases
  As a sales representative
  I need to submit an order for processing
Feature: Approve credit orders
  In order to control financial risk
  As a credit manager
  I need to review and approve orders exceeding credit limits

Bad Examples:

# ❌ Too technical
Feature: Order API endpoint
  In order to save order data to the database
  As the system
  I need to expose an order creation endpoint

# ❌ Describes a rule, not a capability
Feature: Validate customer credit
  In order to prevent bad debt
  As the system
  I need to check credit limits before accepting orders

# ❌ Too vague
Feature: Orders
  As a user
  I want to work with orders

5.2 Identifying Real Features

Use this decision tree:

Is it a distinct business capability?
├─ YES → Is it independent?
│  ├─ YES → Is removing it meaningful to users?
│  │  ├─ YES → It's a feature ✓
│  │  └─ NO → It's probably a rule
│  └─ NO → It depends on another feature
└─ NO → Is it a permission/policy/config?
   └─ YES → It's a rule, not a feature

5.3 Feature Granularity

Too coarse:

# ❌ Too broad
Feature: Sales operations

Too fine:

# ❌ These are behaviors within a capability
Feature: Add product to order
Feature: Remove product from order
Feature: Update order quantity

Just right:

# ✓ Correct granularity
Feature: Place an order

5.4 When Configuration Isn't a Feature

Configuration flags, tenant settings, and feature toggles are never features.

They are rules that constrain features.

Wrong:

Feature: Enable discounts
Feature: Require customer signatures
Feature: Allow partial payments

Right:

Feature: Place an order
  
  Rule: Discounts may only be applied when allowed by the business
  
  Rule: An order may require additional details before submission
  
  Rule: An order may include payment information

6. Writing Rules

6.1 Rule Purpose

Rules explicitly document the constraints and policies that govern a feature.

They answer: "Under what conditions can this action succeed or fail?"

6.2 Rule Formatting

Rule: <what must be true>

Characteristics of good rules:

  • Describe what, never how
  • Use declarative language
  • State the constraint clearly
  • Avoid implementation details
  • Focus on business concepts

6.3 Good Rule Examples

Rule: Orders may only be placed for customers in the active route plan

Rule: Credit orders must satisfy credit and approval policies

Rule: Product prices are determined automatically based on business configuration

Rule: An order consists of one or more order items

Rule: Discounts may only be applied when allowed by the business

Rule: Only authorized users may place orders

6.4 Bad Rule Examples

# ❌ Describes implementation
Rule: Check route_plan_id against customer assignments table

# ❌ Too technical
Rule: Validate request payload contains required fields

# ❌ Restates the feature
Rule: Orders can be placed

# ❌ Tautological/redundant
Rule: An order must be valid before submission

# ❌ UI-focused
Rule: The submit button is disabled until form is complete

6.5 When to Create a New Rule

Create a new rule when:

  • A distinct business policy applies
  • A new constraint affects success/failure
  • Configuration changes behavior
  • Different permissions apply
  • Approval workflows differ

Don't create rules for:

  • Implementation details
  • Technical validations
  • UI states
  • Every possible edge case

6.6 Rule Organization

Group rules logically by concern:

Feature: Place an order
  
  # Order construction
  Rule: An order consists of one or more order items
  
  # Pricing
  Rule: Product prices are determined automatically based on business configuration
  
  # Constraints
  Rule: Orders may only be placed for customers in the active route plan
  
  # Permissions
  Rule: Only authorized users may place orders
  
  # Financial policies
  Rule: Credit orders must satisfy credit and approval policies

7. Writing Scenarios

7.1 Scenario Purpose

Scenarios provide concrete examples that:

  • Demonstrate how rules work in practice
  • Show both success and failure paths
  • Clarify ambiguous requirements
  • Serve as acceptance criteria
  • Enable automated testing

7.2 The Friends Episode Notation (Mandatory)

All scenarios must use this format:

Scenario: The one where <something happens>

Why this format?

  • Forces descriptive, memorable names
  • Prevents generic names like "Valid order" or "Test 1"
  • Makes scenarios easy to reference in conversation
  • Adds a touch of personality while remaining professional

Examples:

Scenario: The one where a product is added to the order
Scenario: The one where the customer is not in the active route plan
Scenario: The one where approval is required for a credit order
Scenario: The one where a discount promotion is applied
Scenario: The one where the same product is added multiple times

7.3 Given-When-Then Structure

Every scenario follows this pattern:

Scenario: The one where <something happens>
  Given <context and preconditions>
  When <one business action>
  Then <observable business outcome>

Given: Context

Purpose: Establish the world state before the action

What to include:

  • Who is performing the action
  • What permissions they have
  • What business state exists
  • Relevant configuration
  • Existing data
  • Specific values and quantities

Good Examples:

Given customer "Acme Store" has credit limit of 10000.00
Given "Coca Cola 500ml" batch "B123" has 50 cartons in stock
Given the sales representative has price list "Standard Wholesale"
Given a promotion offers 10% discount on "Coca Cola 500ml" with minimum 10 cartons
Given customer "Acme Store" must sell categories "Soft Drinks" and "Water"

Bad Examples:

# ❌ Too technical
Given the database contains customer record ID 12345

# ❌ UI-focused
Given the user is on the order creation page

# ❌ Implementation details
Given the OrderService is initialized

# ❌ Too vague
Given a customer with a credit limit
Given a product with stock
Given discounts are configured

When: Action

Purpose: Describe one intentional business action

Rules:

  • Exactly one action per scenario
  • Use business terminology
  • Present tense
  • Active voice
  • Include specific values

Good Examples:

When "Coca Cola 500ml" with quantity 10 cartons is added to the order
When the quantity is changed to 15 cartons
When a 5% discount is applied to the item
When payment of 1000.00 is recorded
When the order is placed

Bad Examples:

# ❌ Multiple actions
When the product is added and the discount is applied and the order is saved

# ❌ Technical
When the POST request is sent to /api/orders

# ❌ UI-focused
When the user clicks the Submit button

# ❌ Too vague
When a product is added
When the order is processed

Then: Outcome

Purpose: Describe observable business outcome with specific, measurable results

What to include:

  • Success or failure state
  • Changes to business entities
  • Side effects visible to users
  • Error conditions (in business terms)
  • Concrete values and quantities

Good Examples:

Then the order contains "Coca Cola 500ml" with quantity 10 cartons
Then the selling price is 95.00 per carton
Then inventory is reduced to 40 cartons
Then the order is rejected
Then the order is rejected due to insufficient stock
Then the order payment status is "Fully paid"
Then both payments are included in the order

Bad Examples:

# ❌ Implementation
Then the order record is inserted into the database

# ❌ UI state
Then the success message is displayed

# ❌ Too vague
Then it works
Then the order is successful
Then the price is correct
Then stock is updated

# ❌ Implementation detail - specific error message wording
Then the error message is "ERR_001: Insufficient inventory"
Then the error displays "Stock validation failed"

Note on Error Messages:

Exact error message wording is an implementation detail and should generally be avoided in scenarios. Focus on the business outcome:

❌ Too specific (ties you to exact wording):

Then the error message is "You have 5 cartons of Coca Cola 500ml left in stock"

✅ Business outcome (flexible on wording):

Then the order is rejected due to insufficient stock

Exception: Include specific error messages only when:

  • The exact wording is a regulatory/compliance requirement
  • The message contains critical business information that affects user decisions
  • You're documenting a user-facing error that must be precise for support purposes

In those cases, document it as a separate assertion:

Then the order is rejected due to insufficient stock
And the user is informed of the available quantity

7.4 Writing Specific, Not Vague Scenarios

The Specificity Principle:

Every scenario should use concrete values, real product names, actual quantities, and specific error messages.

Vague vs Specific Examples:

❌ Vague✅ Specific
Given a product with stockGiven "Coca Cola 500ml" batch "B123" has 50 cartons in stock
When the product is addedWhen "Coca Cola 500ml" with quantity 10 cartons is added
Then the correct price is appliedThen the selling price is 95.00 per carton
Given a customer with a credit limitGiven customer "Acme Store" has credit limit of 10000.00
When a discount is appliedWhen a 5% discount is applied to the item
Then an error occursThen the order is rejected due to insufficient stock
Given insufficient stockGiven "Coca Cola 500ml" has 5 cartons in stock
When stock is checkedWhen "Coca Cola 500ml" with quantity 10 cartons is added to a sale

Complete Vague vs Specific Scenario:

❌ Vague:

Scenario: The one where stock validation occurs
  Given a product with limited stock
  When the product is added with high quantity
  Then the system rejects it

✅ Specific:

Scenario: The one where stock is insufficient
  Given "Coca Cola 500ml" batch "B123" has 5 cartons in stock
  When "Coca Cola 500ml" batch "B123" with quantity 10 cartons is added to a sale
  Then the item is rejected due to insufficient stock

Why Specificity Matters:

  1. Developers know exactly what to implement - "95.00 per carton" not "the correct price"
  2. Testers can verify precisely - Check for business outcome, not exact UI text
  3. Business stakeholders recognize real scenarios - "Acme Store" not "a customer"
  4. Documentation serves as examples - Can be used in training and support
  5. Removes ambiguity - No guessing about what "correct" or "valid" means
  6. Focuses on business behavior - Not tied to UI implementation details

7.5 One Behavior Per Scenario

Each scenario demonstrates exactly one rule or behavior.

Wrong: Multiple behaviors

Scenario: The one where an order is validated and submitted
  Given a sales representative is placing an order
  When a product is added with an invalid quantity
  Then the order is rejected
  And when a valid product is added
  Then the order is submitted successfully

Right: Separate scenarios

Scenario: The one where an invalid quantity is rejected
  Given a sales representative is placing an order
  When a product with quantity 0 is added to the order
  Then the order is rejected

Scenario: The one where a valid order is submitted
  Given a sales representative has added valid products to an order
  When the order is placed
  Then the order is submitted successfully

7.6 Scenario Independence

Each scenario must be:

  • Self-contained — doesn't depend on other scenarios
  • Runnable in any order — no sequence dependencies
  • Isolated — creates its own test data

Wrong:

Scenario: The one where a product is added
  When a product is added to the order
  Then the order contains one product

Scenario: The one where another product is added
  # ❌ Assumes previous scenario ran
  When another product is added to the order
  Then the order contains two products

Right:

Scenario: The one where a product is added to an empty order
  Given a sales representative is placing an order
  When a product is added to the order
  Then the order contains the product

Scenario: The one where a product is added to an existing order
  Given an order already contains one product
  When another product is added to the order
  Then the order contains two products

7.7 Positive and Negative Cases

For each rule, document:

  1. Happy path — constraint satisfied
  2. Violation — constraint not satisfied

Example:

Rule: Orders may only be placed for customers in the active route plan

  Scenario: The one where customer is in route plan
    Given customer "Acme Store" is in today's active route plan
    When the order is placed
    Then the order is submitted successfully

  Scenario: The one where customer is not in route plan
    Given customer "Acme Store" is not in today's active route plan
    When the order is placed
    Then the order is rejected

7.8 Configuration Variants

When behavior changes based on configuration, show both states:

Rule: Discounts may only be applied when allowed by the business

  Scenario: The one where discounts are allowed
    Given discounts are enabled by business configuration
    When a discount is applied to an order item
    Then the discount is reflected in the order total

  Scenario: The one where discounts are not allowed
    Given discounts are disabled by business configuration
    When a discount is applied to an order item
    Then the order is rejected

7.9 When to Use Scenario Outlines

Use Scenario Outlines only when:

  • The business intent is identical
  • Only data values change
  • Examples are truly interchangeable

Good use:

Scenario Outline: The one where different UOMs have different prices
  Given a product with prices for multiple UOMs
  When the product is added with UOM <uom>
  Then the price is <price>
  
  Examples:
    | uom    | price |
    | pieces | 10.00 |
    | carton | 95.00 |
    | pallet | 900.00|

Bad use:

# ❌ Different business intents
Scenario Outline: The one where validation occurs
  Given <context>
  When <action>
  Then <result>
  
  Examples:
    | context              | action            | result   |
    | invalid customer     | order placed      | rejected |
    | no products          | order placed      | rejected |
    | exceeds credit limit | order placed      | pending  |

8. Using Tags

8.1 What Are Tags?

Tags are metadata annotations that can be added to features, rules, or scenarios to:

  • Categorize scenarios by business domain, component, or concern
  • Filter which scenarios to run in different contexts
  • Organize documentation for different audiences
  • Track non-functional requirements (performance, security, etc.)
  • Manage test execution strategy

Tags are written with the @ symbol and placed on the line before the element they annotate.

@smoke @critical
Scenario: The one where a product is added to an empty order
  Given a sales representative is placing an order for customer "Acme Store"
  When "Coca Cola 500ml" with quantity 10 cartons is added to the order
  Then the order contains "Coca Cola 500ml" with quantity 10 cartons

8.2 Tag Placement Rules

Tags can be placed at three levels:

  1. Feature level — applies to all scenarios in the feature
  2. Rule level — applies to all scenarios under that rule
  3. Scenario level — applies only to that specific scenario
@orders @financial
Feature: Place an order
  
  @pricing
  Rule: Product prices are determined by price list hierarchy
    
    @smoke @critical
    Scenario: The one where customer group price list overrides user price list
      Given the sales representative has price list "Standard Wholesale"
      When "Coca Cola 500ml" with quantity 1 carton is added
      Then the selling price is 90.00 per carton
    
    @edge-case
    Scenario: The one where net price is used for configured customers
      Given customer "Acme Store" is configured to use net prices
      When "Coca Cola 500ml" is added to the order
      Then the selling price is 85.00

Tag inheritance:

  • Scenarios inherit tags from their Rule
  • Scenarios inherit tags from their Feature
  • A scenario tagged @smoke under a feature tagged @orders effectively has both tags

8.3 Standard Tag Categories

8.3.1 Test Execution Tags

These tags control when and how scenarios are executed:

TagPurposeUsage
@smokeCritical path scenarios that must always workRun before every deployment
@regressionFull regression suiteRun nightly or before releases
@acceptanceUser acceptance scenariosRun before client demos
@integrationRequires multiple systemsRun in integration environment
@manualCannot be automated yetExcluded from automated runs
@wipWork in progress, not readyExcluded from CI/CD
@skipTemporarily disabledDocumented reason required

Example:

@smoke @critical
Scenario: The one where credit is within limit
  Given customer "Acme Store" has credit limit of 10000.00
  And current balance is 3000.00
  When a credit order totaling 5000.00 is placed
  Then the order is submitted successfully

@regression
Scenario: The one where volume discount applies to large order
  Given customer "Acme Store" has volume discounts configured
  And ordering 100 cartons qualifies for volume pricing
  When "Coca Cola 500ml" with quantity 100 cartons is added
  Then the discounted price is applied

8.3.2 Business Domain Tags

Group scenarios by business capability or domain area:

TagDomain
@ordersOrder placement and management
@paymentsPayment collection and processing
@inventoryStock management
@pricingPrice calculation and special prices
@promotionsPromotional campaigns
@creditCredit management
@customersCustomer management
@productsProduct catalog

Example:

@orders @pricing @promotions
Feature: Place an order
  
  @pricing @special-prices
  Rule: Special prices apply when minimum quantity is met
    
    Scenario: The one where special price applies
      Given customer "Acme Store" has special price for "Coca Cola 500ml"
      When "Coca Cola 500ml" with quantity 5 cartons is added
      Then the selling price is 92.00 per carton

8.3.3 Priority and Risk Tags

Indicate business criticality and risk level:

TagMeaning
@criticalBusiness-critical functionality
@high-priorityImportant but not critical
@low-priorityNice to have
@high-riskComplex or error-prone area
@complianceRegulatory or compliance requirement

Example:

@critical @compliance
Scenario: The one where credit limit must be respected
  Given customer "Acme Store" has credit limit of 10000.00
  And current balance is 8000.00
  When a credit order totaling 5000.00 is placed
  Then the order is rejected
  And the error message indicates credit limit exceeded

8.3.4 Technical Characteristic Tags

Document non-functional requirements:

TagCharacteristic
@performancePerformance-sensitive scenario
@securitySecurity-related behavior
@slowTakes longer than 5 seconds
@databaseRequires database
@external-apiCalls external services
@offlineMust work without network

Example:

@performance @slow
Scenario: The one where 1000 order items are processed
  Given an order with 1000 different products
  When promotions are applied to all items
  Then the calculation completes within 10 seconds

@security @compliance
Scenario: The one where user without permission cannot place orders
  Given the sales representative does not have "place orders" permission
  When the order is placed
  Then the order is rejected due to insufficient permissions

8.3.5 Configuration and Environment Tags

Specify when scenarios apply:

TagEnvironment/Config
@productionOnly relevant in production
@stagingOnly for staging environment
@feature-flag:discount-approvalRequires specific feature flag
@role:adminOnly for admin users
@tenant:enterpriseEnterprise tenant only
@mobileMobile application specific
@webWeb application specific
@backendBackend/API specific
@offline-capableWorks in offline mode

Example:

@feature-flag:blanket-agreements @backend
Scenario: The one where blanket agreement price is applied
  Given customer "Acme Store" has blanket agreement "BA-2024-001" for "Coca Cola 500ml" at 88.00
  And the blanket agreement has remaining balance of 100 cartons
  When "Coca Cola 500ml" with quantity 10 cartons is added
  Then the selling price is 88.00 per carton

@tenant:premium @role:credit-manager @web
Scenario: The one where credit order requires manager approval
  Given customer "Acme Store" has credit limit of 10000.00
  And current balance is 8000.00
  And credit approval is required for orders exceeding limit
  When a credit order totaling 5000.00 is placed
  Then the order status is "Pending Approval"
  And the credit manager can review the order via web portal

@mobile @offline-capable
Scenario: The one where order is placed without network connectivity
  Given the mobile device has no network connectivity
  When an order for customer "Acme Store" totaling 1500.00 is placed
  Then the order is saved on the device
  And the sales representative can continue working
  And the order will be submitted when connectivity is restored

8.3.6 Platform and Channel Tags

Specify which platform or channel the scenario applies to:

TagPlatform/Channel
@mobileMobile application (iOS/Android)
@mobile:iosiOS specific
@mobile:androidAndroid specific
@webWeb application
@backendBackend services/APIs
@apiAPI endpoints
@desktopDesktop application
@ussdUSSD channel
@posPoint of sale terminal

Example:

@mobile @mobile:ios @high-priority
Scenario: The one where barcode scanner captures product
  Given a sales representative is on the add product screen
  When the barcode scanner is activated
  And barcode "7891234567890" is scanned
  Then "Coca Cola 500ml" is added to the order

@mobile:android @bug:MOBILE-456 @fixed
Scenario: The one where signature capture works on Android
  Given customer signature is required
  When the signature pad is displayed on Android device
  And the customer signs with their finger
  Then the signature is captured successfully

@backend @integration
Scenario: The one where order is received from external system
  Given an external system submits an order
  When the order data is valid
  Then the order is accepted
  And order confirmation is returned

@web @desktop
Scenario: The one where manager approves credit order from desktop
  Given a credit order is pending approval
  And the credit manager is logged into web portal
  When the order is reviewed and approved
  Then the order status changes to "Approved"
  And the sales representative is notified

@mobile @backend @sync
Scenario: The one where mobile syncs completed orders to backend
  Given 5 orders were completed on mobile device
  And the device has network connectivity
  When sync is initiated
  Then all 5 orders are transmitted to backend
  And mobile receives confirmation for each order

@ussd @limited-input
Scenario: The one where order is placed via USSD menu
  Given a sales representative dials the USSD code
  When they navigate the menu to place order
  And select customer and products
  Then the order is submitted
  And confirmation is displayed on USSD screen

8.4 Tag Naming Conventions

Follow these conventions:

  1. Use lowercase@smoke not @Smoke or @SMOKE
  2. Use hyphens for multi-word tags@high-priority not @highPriority or @high_priority
  3. Be descriptive@payment-integration not @pi
  4. Avoid redundancy — Don't tag a scenario @order-scenario in a feature already tagged @orders
  5. Use prefixes for categories@role:admin, @feature-flag:new-ui

Good:

@smoke @high-priority @feature-flag:multi-payment

Bad:

@SMOKE @highPriority @multiPaymentFeature

8.5 Practical Tagging Strategies

8.5.1 Smoke Test Suite

Create a minimal set of critical scenarios:

Feature: Place an order
  
  @smoke @critical
  Scenario: The one where a basic order is placed successfully
    Given customer "Acme Store" is in today's route plan
    And the sales representative has permission to place orders
    When "Coca Cola 500ml" with quantity 10 cartons is added
    And the order is placed
    Then the order is submitted successfully
  
  @smoke @critical
  Scenario: The one where stock validation prevents overselling
    Given "Coca Cola 500ml" has 5 cartons in stock
    When "Coca Cola 500ml" with quantity 10 cartons is added to a sale
    Then the item is rejected

Run smoke tests with:

# Only scenarios tagged @smoke
cucumber --tags @smoke

# Smoke tests that are also critical
cucumber --tags "@smoke and @critical"

8.5.2 Progressive Test Execution

Build test suites of increasing depth:

@smoke
Scenario: The one where an order is placed

@regression
Scenario: The one where promotions are applied

@regression @edge-case
Scenario: The one where multiple promotions conflict

@regression @edge-case @slow
Scenario: The one where 100 products have promotions calculated

Execution strategy:

  • Every commit: @smoke (2 minutes)
  • Every merge: @smoke and @regression (15 minutes)
  • Nightly: @regression (1 hour)
  • Weekly: All scenarios (3 hours)

8.5.3 Feature Flag Management

Document which scenarios require specific features:

@feature-flag:blanket-agreements
Rule: Blanket agreements take highest priority in pricing
  
  Scenario: The one where blanket agreement price is applied
    # scenario details

@feature-flag:multi-payment
Rule: Multiple payment modes may be used for a single order
  
  Scenario: The one where cash and M-Pesa are combined
    # scenario details

Run only enabled features:

# Only scenarios for enabled features
cucumber --tags "@feature-flag:blanket-agreements or @feature-flag:multi-payment"

# Exclude disabled features
cucumber --tags "not @feature-flag:disabled-feature"

8.5.4 Component-Based Organization

Tag by system component for targeted testing:

@orders @pricing-engine @backend
Scenario: The one where price is calculated from price list

@orders @inventory-service @backend
Scenario: The one where stock is validated

@orders @promotions-engine @backend
Scenario: The one where discount is applied

@orders @payment-gateway @external-api @mobile
Scenario: The one where M-Pesa payment is verified

@orders @barcode-scanner @mobile
Scenario: The one where product is scanned

Run component-specific tests:

# Test pricing engine changes
cucumber --tags @pricing-engine

# Test all mobile order scenarios
cucumber --tags "@orders and @mobile"

# Test backend integrations only
cucumber --tags "@backend and @external-api"

# Test mobile-specific features excluding iOS
cucumber --tags "@mobile and not @mobile:ios"

8.5.5 Cross-Platform Behavior

Document scenarios that apply to multiple platforms within the main business feature:

@orders @mobile @backend
Feature: Place an order
  
  @mobile @offline-capable
  Rule: Orders can be placed without network connectivity
    
    @smoke @critical
    Scenario: The one where an order is placed offline
      Given the mobile device has no network connectivity
      When an order totaling 1500.00 is placed
      Then the order is saved on the device
      And the order will be submitted when connectivity is restored

    @regression
    Scenario: The one where offline orders are submitted when online
      Given 3 orders were saved offline on mobile device
      When network connectivity is restored
      Then all 3 orders are submitted to the system
      And each order receives confirmation

  @mobile:ios @mobile:android
  Rule: Orders can be placed on both iOS and Android platforms
    
    @smoke
    Scenario: The one where an order is placed on iOS
      Given a sales representative is using an iPhone
      When an order is placed
      Then the order is submitted successfully

    @smoke
    Scenario: The one where an order is placed on Android
      Given a sales representative is using an Android device
      When an order is placed
      Then the order is submitted successfully

8.5.6 Platform-Specific Behavior

When to create platform-specific scenarios:

Only create separate scenarios per platform when:

  1. Business behavior differs between platforms (not just implementation)
  2. User experience is fundamentally different (mobile camera vs web upload)
  3. Different capabilities exist (offline on mobile, bulk operations on web)

Don't create platform-specific scenarios when:

  1. Same business rule applies across all platforms
  2. Only technical implementation differs (iOS camera API vs Android camera API)
  3. Testing platform quirks (use automated tests, not feature documentation)

Example of VALID platform differences (different user experiences):

@mobile @camera
Rule: LPO documentation may be captured via device camera

  @mobile
  Scenario: The one where LPO photo is captured on mobile
    Given LPO documentation is required
    And the sales representative is using a mobile device
    When a photo of the LPO document is captured
    Then the photo is attached to the order

@web @file-upload
Rule: LPO documentation may be uploaded from web

  @web
  Scenario: The one where LPO document is uploaded from web
    Given LPO documentation is required
    And the manager is using web portal
    When a PDF file "LPO-2024-001.pdf" is uploaded
    Then the document is attached to the order

Example of INVALID platform duplication (same business rule):

# ❌ Don't do this - implementation details, not business differences
@mobile:ios
Scenario: The one where LPO photo is captured on iPhone
  Given LPO documentation is required
  And the sales rep is using an iPhone
  When the camera is activated
  And a photo of the LPO document is taken
  Then the photo is attached to the order

@mobile:android
Scenario: The one where LPO photo is captured on Android
  Given LPO documentation is required
  And the sales rep is using Android device
  When the camera is activated
  And a photo of the LPO document is taken
  Then the photo is attached to the order

# ✅ Do this instead - one scenario with platform tags
@mobile @camera @mobile:ios @mobile:android
Scenario: The one where LPO photo is captured on mobile
  Given LPO documentation is required
  When a photo of the LPO document is captured via device camera
  Then the photo is attached to the order

The guiding principle:

Platform should never appear in scenario names or Given/When/Then steps
unless the business behavior actually differs by platform.

Examples of incorrect platform mentions:

# ❌ Wrong - stock validation is same business rule everywhere
Scenario: The one where stock is insufficient on mobile
  Given "Coca Cola 500ml" has 5 cartons in stock
  When the product is added to a sale on mobile
  Then the item is rejected due to insufficient stock

# ❌ Wrong - permission check is same business rule everywhere  
Scenario: The one where user lacks permission on mobile
  Given the user does not have "place orders" permission
  And they are using the mobile app
  When they attempt to place an order
  Then the order is rejected

# ✅ Correct - platform in tags only, business rule is universal
@mobile @web @backend
Scenario: The one where stock is insufficient
  Given "Coca Cola 500ml" has 5 cartons in stock
  When the product is added to a sale
  Then the item is rejected due to insufficient stock

When platform SHOULD appear (different business behaviors):

# ✅ Correct - fundamentally different capabilities
@mobile
Scenario: The one where order is placed without network connectivity
  Given the mobile device has no network connectivity
  When an order is placed
  Then the order is saved on the device

# This wouldn't make sense on web - web requires connectivity
# So platform context is part of the business rule

If the scenarios read identically except for the platform name,
they should be ONE scenario with platform tags,
not separate scenarios.

Use tags for platform targeting, not scenario content:

# Run the same business rule test on different platforms
@mobile @web @backend
Scenario: The one where stock is insufficient
  # scenario steps...

# Then run specific platforms:
cucumber --tags @mobile     # Test on mobile
cucumber --tags @web        # Test on web  
cucumber --tags @backend    # Test backend API

Link scenarios to defect tickets:

@bug:ORD-1234 @fixed
Scenario: The one where decimal quantities caused rounding errors
  Given fractional quantities are allowed
  When "Coca Cola 500ml" with quantity 10.5 cartons is added
  Then the selling price is calculated correctly for 10.5 cartons

@bug:ORD-1235 @wip
Scenario: The one where promotions don't apply to service products
  Given "Installation Service" is a service product
  When the product qualifies for a promotion
  Then the promotion is not applied

8.6 Tag Combination with Boolean Logic

Most BDD frameworks support tag expressions:

AND logic:

# Scenarios that are both smoke AND critical
cucumber --tags "@smoke and @critical"

OR logic:

# Scenarios that are smoke OR critical
cucumber --tags "@smoke or @critical"

NOT logic:

# All scenarios except manual ones
cucumber --tags "not @manual"

# All scenarios except WIP and skipped
cucumber --tags "not @wip and not @skip"

Complex expressions:

# Smoke tests OR (critical AND not slow)
cucumber --tags "@smoke or (@critical and not @slow)"

# Orders or payments, but not external APIs
cucumber --tags "(@orders or @payments) and not @external-api"

8.7 Tags to Avoid

Don't use tags for:

Scenario numbering: @scenario-1, @scenario-2

  • Scenarios should be independently meaningful

Test implementation details: @uses-selenium, @rest-api-test

  • Features describe business behavior, not how they're tested

Developer names: @john, @team-a

  • Use version control for ownership tracking

Generic placeholders: @todo, @fixme

  • Use @wip with a comment explaining what's needed

Date-based tags: @sprint-23, @Q4-2024

  • Features are timeless; use version control for history

8.8 Documenting Tag Strategy

Create a TAGS.md file in your project:

# Tag Strategy

## Test Execution
- `@smoke` - Critical path, run on every build (< 2 min)
- `@regression` - Full suite, run on merge (< 15 min)
- `@manual` - Not automated, excluded from CI

## Business Domains
- `@orders` - Order placement
- `@payments` - Payment collection
- `@pricing` - Price calculation
- `@promotions` - Promotional campaigns

## Priority
- `@critical` - Business-critical
- `@high-priority` - Important
- `@compliance` - Regulatory requirement

## Feature Flags
- `@feature-flag:<name>` - Requires feature flag

## Running Tests
```bash
# Smoke tests only
npm test -- --tags @smoke

# All orders except manual
npm test -- --tags "@orders and not @manual"

### 8.9 Complete Tagged Example

```gherkin
@orders @financial @critical
Feature: Place an order
  In order to sell products to customers
  As a sales representative
  I need to place an order for a customer

  @pricing @smoke @backend
  Rule: Product prices are determined by price list hierarchy

    @smoke @critical @acceptance
    Scenario: The one where customer group price list overrides user price list
      Given the sales representative has price list "Standard Wholesale" with price 95.00
      And customer "Acme Store" belongs to group "Premium Retailers" with price list "Premium"
      And "Coca Cola 500ml" carton costs 90.00 on "Premium"
      When "Coca Cola 500ml" with quantity 1 carton is added
      Then the selling price is 90.00 per carton

  @pricing @feature-flag:blanket-agreements @high-priority @backend
  Rule: Blanket agreements take highest priority in pricing

    @regression @compliance
    Scenario: The one where blanket agreement price is applied
      Given customer "Acme Store" has blanket agreement "BA-2024-001" for "Coca Cola 500ml" carton at 88.00
      And the blanket agreement has remaining balance of 100 cartons
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the selling price is 88.00 per carton
      And blanket agreement "BA-2024-001" is recorded on the order item

  @promotions @regression @backend
  Rule: Promotions are applied automatically to qualifying orders

    @smoke @critical
    Scenario: The one where percentage discount promotion applies
      Given a promotion offers 10% discount on "Coca Cola 500ml" with minimum 10 cartons
      And standard price is 95.00 per carton
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the selling price is 85.50 per carton
      And promotion type is "Percentage Discount"
    
    @edge-case @slow @performance @backend
    Scenario: The one where promotions are calculated for 100 products
      Given an order with 100 different products
      And each product qualifies for a different promotion
      When all promotions are applied
      Then calculation completes within 5 seconds

  @inventory @smoke @critical @mobile @backend
  Rule: Stock must be sufficient for sales and samples

    @smoke @acceptance
    Scenario: The one where stock is insufficient
      Given "Coca Cola 500ml" batch "B123" has 5 cartons in stock
      When "Coca Cola 500ml" batch "B123" with quantity 10 cartons is added to a sale
      Then the item is rejected due to insufficient stock

  @barcode @mobile @mobile:android @high-priority
  Rule: Products may be added via barcode scanning

    @smoke @mobile:android
    Scenario: The one where barcode scanner captures product on Android
      Given a sales representative is placing an order on Android device
      When barcode "7891234567890" is scanned
      Then "Coca Cola 500ml" is added to the order
      And the default quantity is set to 1 carton

    @mobile:ios @smoke
    Scenario: The one where barcode scanner captures product on iOS
      Given a sales representative is placing an order on iPhone
      When barcode "7891234567890" is scanned
      Then "Coca Cola 500ml" is added to the order
      And the default quantity is set to 1 carton

  @sync @mobile @backend @integration @critical
  Rule: Orders created on mobile must sync to backend

    @smoke @critical
    Scenario: The one where mobile order syncs to backend
      Given an order was completed on mobile device "DEVICE-001"
      And the device has network connectivity
      When sync is initiated
      Then the order is transmitted to backend
      And backend returns server order ID
      And mobile updates local order with server ID

    @offline-capable @mobile @regression
    Scenario: The one where orders are queued when offline
      Given the mobile device is in offline mode
      When an order totaling 1500.00 is completed
      Then the order is saved locally
      And the order is queued for sync
      And the user is notified the order will sync when online

  @security @compliance @critical @mobile @backend
  Rule: Only authorized users may place orders

    @smoke @security
    Scenario: The one where user lacks permission
      Given the sales representative does not have "place orders" permission
      When they attempt to place an order
      Then the order is rejected due to insufficient permissions

  @credit @compliance @critical @high-risk @backend
  Rule: Credit limits must be respected

    @smoke @critical @acceptance
    Scenario: The one where credit exceeds limit
      Given customer "Acme Store" has credit limit of 10000.00
      And current balance is 8000.00
      When a credit order totaling 5000.00 is placed
      Then the order is rejected due to exceeding credit limit

  @signature @mobile @compliance
  Rule: Customer signature may be captured on mobile devices

    @mobile:ios @camera @regression
    Scenario: The one where signature is captured on iPhone
      Given customer signature is required
      And the sales rep is using an iPhone
      When the signature pad is displayed
      And the customer signs with their finger
      Then the signature is captured
      And the signature is attached to the order

    @mobile:android @camera @regression
    Scenario: The one where signature is captured on Android
      Given customer signature is required
      And the sales rep is using an Android device
      When the signature pad is displayed
      And the customer signs with their finger
      Then the signature is captured
      And the signature is attached to the order

  @approval @web @desktop @workflow
  Rule: Credit orders may require manager approval

    @web @critical @compliance
    Scenario: The one where manager approves order
      Given a credit order is pending approval
      And the credit manager reviews the order
      When the manager approves the order
      Then the order status changes to "Approved"
      And the sales representative receives a notification

8.11 Tag Minimalism: Avoiding Tag Overload

The Tag Overload Problem:

Too many tags make features harder to read, maintain, and understand. Tags should enhance, not obscure.

8.11.1 The Minimalism Principle

Use the minimum number of tags necessary to achieve your organizational goals.

Signs of tag overload:

# ❌ Tag overload - 12 tags!
@orders @pricing @backend @api @integration @smoke @critical @acceptance @regression @high-priority @compliance @financial
Scenario: The one where customer group price list overrides user price list
  Given the sales representative has price list "Standard Wholesale"
  When "Coca Cola 500ml" with quantity 1 carton is added
  Then the selling price is 90.00 per carton

Better approach:

# ✅ Minimal tags - only what's necessary
@smoke @critical
Scenario: The one where customer group price list overrides user price list
  Given the sales representative has price list "Standard Wholesale"
  When "Coca Cola 500ml" with quantity 1 carton is added
  Then the selling price is 90.00 per carton

8.11.2 Tag Inheritance Strategy

Leverage tag inheritance to avoid repeating tags:

# ❌ Repetitive - every scenario tagged @orders @pricing @backend
@orders @pricing @backend
Feature: Place an order

  Rule: Product prices are determined by price list hierarchy
    
    @orders @pricing @backend @smoke
    Scenario: The one where price is calculated
    
    @orders @pricing @backend @regression
    Scenario: The one where price changes with quantity

# ✅ Inherited - feature-level tags apply to all scenarios
@orders @pricing @backend
Feature: Place an order

  Rule: Product prices are determined by price list hierarchy
    
    @smoke
    Scenario: The one where price is calculated
    
    @regression
    Scenario: The one where price changes with quantity

Tag inheritance levels:

  1. Feature level — Broad categorization (domain, platform)
  2. Rule level — Specific concern within feature
  3. Scenario level — Execution strategy and specifics

8.11.3 Choose Your Tag Strategy

Option A: Minimal Execution Tags Only

Focus only on what controls test execution:

@orders
Feature: Place an order

  Rule: Product prices are determined by price list hierarchy
    
    @smoke
    Scenario: The one where customer group price overrides user price
    
    @regression
    Scenario: The one where volume discounts apply

Benefits:

  • Clean, readable
  • Easy to maintain
  • Focuses on test strategy

When to use: Small teams, simple CI/CD, single platform

Option B: Selective Strategic Tags

Add only tags that serve a clear purpose:

@orders
Feature: Place an order

  @backend
  Rule: Product prices are determined by price list hierarchy
    
    @smoke @critical
    Scenario: The one where customer group price overrides user price
    
    @regression @performance
    Scenario: The one where 1000 prices are calculated

  @mobile @backend @sync
  Rule: Orders created on mobile must sync to backend
    
    @smoke @critical
    Scenario: The one where mobile order syncs to backend

Benefits:

  • Balances readability with organization
  • Platform clarity where needed
  • Performance tests identified

When to use: Multi-platform systems, medium teams, targeted testing

Option C: Comprehensive Tagging

Use multiple tags for detailed organization:

@orders @financial
Feature: Place an order

  @pricing @backend @critical
  Rule: Product prices are determined by price list hierarchy
    
    @smoke @acceptance @high-priority
    Scenario: The one where customer group price overrides user price

  @mobile @backend @sync @integration @critical
  Rule: Orders created on mobile must sync to backend
    
    @smoke @critical @offline-capable
    Scenario: The one where orders queue when offline

Benefits:

  • Maximum flexibility
  • Detailed reporting
  • Complex filtering

When to use: Large teams, multiple platforms, complex CI/CD, compliance requirements

8.11.4 The Three-Tag Rule

General guideline: Most scenarios should have 3 or fewer scenario-level tags.

@orders @mobile
Feature: Place an order

  Rule: Products may be added via barcode scanning
    
    # ✅ Good: 2 scenario-level tags
    @smoke @mobile:android
    Scenario: The one where barcode scanner captures product
    
    # ⚠️ Acceptable: 3 scenario-level tags
    @regression @performance @slow
    Scenario: The one where 100 products are scanned
    
    # ❌ Too many: 5+ scenario-level tags
    @smoke @critical @acceptance @high-priority @compliance
    Scenario: The one where product is added

Exceptions: Integration scenarios involving multiple systems may need more tags:

# Acceptable for cross-system scenario
@mobile @backend @payment-gateway @external-api @integration
Scenario: The one where mobile payment syncs to backend and gateway

8.11.5 Tag Consolidation Strategies

Strategy 1: Use Composite Tags

Instead of multiple related tags, create composite tags:

# ❌ Before: Too many individual tags
@critical @smoke @acceptance @high-priority

# ✅ After: One composite tag
@p0  # Priority 0 = critical smoke tests

# Or use tag expressions in execution
cucumber --tags "@critical and @smoke"

Strategy 2: Infer from Context

Don't tag what's obvious from the feature or rule:

# ❌ Redundant tagging
@orders @pricing
Feature: Place an order

  @orders @pricing  # ← Redundant, inherited from feature
  Rule: Product prices are determined automatically
    
    @orders @pricing  # ← Even more redundant
    Scenario: The one where price is calculated

# ✅ Clean - tags only what's additional
@orders @pricing
Feature: Place an order

  Rule: Product prices are determined automatically
    
    @smoke
    Scenario: The one where price is calculated

Strategy 3: Platform Tags at Feature/Rule Level

Put platform tags where the entire rule applies:

# ❌ Repetitive platform tags
Feature: Place an order

  Rule: Products may be added via barcode
    
    @mobile @mobile:ios
    Scenario: The one where barcode scans on iOS
    
    @mobile @mobile:android
    Scenario: The one where barcode scans on Android

# ✅ Better - platform at rule level
Feature: Place an order

  @mobile
  Rule: Products may be added via barcode
    
    @mobile:ios
    Scenario: The one where barcode scans on iOS
    
    @mobile:android
    Scenario: The one where barcode scans on Android

8.11.6 When to Use Each Tag Type

Always use (at appropriate level):

  • Execution strategy: @smoke, @regression
  • Platform (if multi-platform): @mobile, @backend, @web

Use sparingly:

  • Priority: Only for truly critical scenarios
  • Performance: Only for actual performance tests
  • Domain: Only at feature level

Rarely use:

  • Technical characteristics: Only when it changes test strategy
  • Environment: Only when scenario truly environment-specific

Almost never use at scenario level:

  • Business domain (put at feature level)
  • Company/team tags (use version control)
  • Date-based tags (use version control)

8.11.7 Tag Audit Checklist

Before adding a tag, ask:

  • Does this tag serve a specific, documented purpose?
  • Would removing this tag make anything harder?
  • Is this tag unique enough to be useful for filtering?
  • Could this be inherited from feature/rule level?
  • Am I duplicating information already in the scenario description?
  • Will someone else understand why this tag exists?

If you answer "no" to any of these, reconsider the tag.

8.11.8 Real-World Example: Progressive Refinement

Initial version (tag overload):

@orders @sales @financial @critical @high-priority @backend @api @integration @pricing
Feature: Place an order

  @orders @pricing @backend @critical @smoke @acceptance @regression
  Rule: Product prices are determined automatically
    
    @orders @pricing @backend @critical @smoke @acceptance @p0 @happy-path
    Scenario: The one where customer group price overrides user price

After refinement (minimal and clear):

@orders @backend
Feature: Place an order

  Rule: Product prices are determined automatically
    
    @smoke @critical
    Scenario: The one where customer group price overrides user price

What was removed and why:

  • @sales, @financial — Too generic, covered by @orders
  • @high-priority — Redundant with @critical
  • @api, @integration — Implementation details
  • @acceptance, @regression@smoke implies these
  • @pricing — Obvious from rule name
  • @p0, @happy-path — Covered by @critical and @smoke

8.11.9 Team Agreement Template

Create a TAG_POLICY.md:

# Tag Policy

## Our Approach
We use **Option B: Selective Strategic Tags** - minimal tags with clear purpose.

## Mandatory Tags
- Every scenario: One execution tag (`@smoke`, `@regression`, or `@manual`)
- Multi-platform features: Platform tag at feature or rule level

## Optional Tags
- `@critical` - Only for business-critical scenarios (< 10% of scenarios)
- `@slow` - Only for tests taking > 10 seconds
- `@external-api` - Only when calling actual external services

## Forbidden Tags
- Never use `@test`, `@scenario`, `@feature` (redundant)
- Never use developer names or team names
- Never use date-based tags
- Never duplicate scenario-level tags already at feature/rule level

## Maximum Tags
- Feature level: 3 tags maximum
- Rule level: 2 tags maximum  
- Scenario level: 3 tags maximum (except cross-system integration)

## Review Criteria
- If a PR adds more than 2 new tags, it requires justification
- All tags must be documented in TAGS.md
- Unused tags must be removed quarterly

8.11.10 The Golden Rules of Tagging

  1. Less is more — Start with minimal tags, add only when needed
  2. Inherit, don't repeat — Use feature/rule level tags
  3. Purpose over pattern — Every tag must serve a documented purpose
  4. Readable first — Scenarios are documentation; tags are metadata
  5. Review regularly — Remove unused tags every quarter

Remember:

Tags are organizational tools, not documentation.
If you need many tags to explain what a scenario does,
the scenario description needs improvement, not more tags.


Remember:

  • Tags are metadata, not documentation
  • Don't rely on tags to explain business rules
  • Business stakeholders read scenarios, not tags
  • Tags support execution and organization, not understanding

Good: Tags supplement clear scenarios

@smoke @critical
Scenario: The one where credit limit prevents over-extension
  Given customer "Acme Store" has credit limit of 10000.00
  And current balance is 8000.00
  When a credit order totaling 5000.00 is placed
  Then the order is rejected

Bad: Tags replace clear naming

@credit @limit @validation @negative
Scenario: Test case 1
  Given limit 10000
  When order 5000
  Then rejected

Tags enhance organization and execution strategy, but scenarios must stand alone as readable documentation.


9. Organizing Features into Modules

9.1 What Are Modules?

Modules are logical groupings of related features that represent a coherent business domain or subdomain.

As your system grows, organizing features into modules:

  • Improves discoverability - easier to find related features
  • Supports team organization - teams can own modules
  • Enables independent evolution - modules can be versioned separately
  • Reflects business structure - mirrors how the business thinks about capabilities

9.2 Module vs Feature vs Rule

Understanding the hierarchy:

Module (Domain Area)
└── Feature (Business Capability)
    └── Rule (Constraint)
        └── Scenario (Example)

Example:

Orders Module
├── Place an order (Feature)
│   ├── Stock must be sufficient (Rule)
│   ├── Prices are determined automatically (Rule)
│   └── Credit limits must be respected (Rule)
├── Approve credit orders (Feature)
│   ├── Only managers can approve (Rule)
│   └── Approval history is recorded (Rule)
└── Cancel an order (Feature)
    └── Only pending orders can be cancelled (Rule)

9.3 Identifying Modules

Ask: "What major business domains exist in our system?"

Good modules (business domains):

  • Orders
  • Payments
  • Inventory
  • Customers
  • Products
  • Pricing
  • Promotions
  • Route Planning
  • Reporting

Not modules (too granular):

  • ❌ Order Validation (part of Orders)
  • ❌ Price Calculation (part of Pricing)
  • ❌ Stock Checking (part of Inventory)

Not modules (too broad):

  • ❌ Sales (too vague - contains Orders, Payments, Customers)
  • ❌ Operations (too vague - what does this mean?)

9.4 File Structure for Modules

Option A: Flat structure with prefixes

features/
├── orders_place_order.feature
├── orders_approve_order.feature
├── orders_cancel_order.feature
├── payments_collect_payment.feature
├── payments_process_refund.feature
├── inventory_adjust_stock.feature
└── inventory_transfer_stock.feature

Pros: Simple, all features in one directory Cons: Doesn't scale well beyond 20-30 features

Option B: Module directories (Recommended)

features/
├── orders/
│   ├── place_order.feature
│   ├── approve_credit_order.feature
│   └── cancel_order.feature
├── payments/
│   ├── collect_payment.feature
│   └── process_refund.feature
├── inventory/
│   ├── adjust_stock.feature
│   └── transfer_stock.feature
├── customers/
│   ├── register_customer.feature
│   └── update_customer_details.feature
└── pricing/
    ├── manage_price_lists.feature
    └── apply_special_prices.feature

Pros: Scalable, clear organization, easy navigation Cons: Requires directory navigation

Option C: Domain-driven directory structure

features/
├── sales/
│   ├── orders/
│   │   ├── place_order.feature
│   │   └── approve_order.feature
│   ├── payments/
│   │   └── collect_payment.feature
│   └── customers/
│       └── register_customer.feature
├── operations/
│   ├── inventory/
│   │   └── adjust_stock.feature
│   └── route_planning/
│       └── plan_route.feature
└── analytics/
    └── reporting/
        └── generate_sales_report.feature

Pros: Reflects bounded contexts, supports large systems Cons: Can be over-engineered for smaller systems

9.5 Naming Conventions for Module Files

Use lowercase with underscores:

  • place_order.feature
  • collect_payment.feature
  • PlaceOrder.feature
  • place-order.feature

File name should match feature name:

# File: place_order.feature
Feature: Place an order

Keep names action-oriented:

  • place_order.feature
  • collect_payment.feature
  • order.feature (too vague)
  • order_placement.feature (noun form)

9.6 Module Documentation

Create a README.md in each module directory:

# Orders Module

## Purpose
Manages the complete order lifecycle from creation to fulfillment.

## Features
- **Place an order** - Sales representatives place orders for customers
- **Approve credit order** - Credit managers approve orders exceeding limits
- **Cancel an order** - Cancel pending orders before fulfillment

## Business Rules
- Orders can only be placed for customers in active route plans
- Credit orders require manager approval above credit limit
- Only pending orders can be cancelled

## Key Stakeholders
- Sales representatives
- Credit managers
- Warehouse managers

## Related Modules
- **Payments** - Payment collection for orders
- **Inventory** - Stock validation and reservation
- **Customers** - Customer information and credit limits

## Running Tests
```bash
# All order features
cucumber features/orders

# Smoke tests only
cucumber features/orders --tags @smoke

### 9.7 Cross-Module Dependencies

**Problem:** Features often depend on capabilities from other modules.

**Example:**
```gherkin
# File: orders/place_order.feature
Feature: Place an order
  
  Rule: Payment must be collected for cash sales
    
    Scenario: The one where payment is collected
      Given a sales representative is placing a cash sale
      When payment of 1000.00 is collected  # ← This is from Payments module
      Then the order is submitted successfully

Guidelines for cross-module scenarios:

  1. Keep the scenario in the primary module (where the main action happens)
  2. Reference other module capabilities naturally (as Given or Then steps)
  3. Don't duplicate scenarios across modules
  4. Use tags to indicate dependencies
@orders @payments
Scenario: The one where payment is collected for cash sale
  Given a sales representative is placing a cash sale
  When payment of 1000.00 is collected
  Then the order is submitted successfully
  And payment is recorded

9.8 Module Tagging Strategy

Tag features at the module level:

@orders
Feature: Place an order
  
  @orders @pricing
  Rule: Product prices are determined automatically
  
  @orders @inventory
  Rule: Stock must be sufficient for sales

Benefits:

  • Run all features in a module: cucumber --tags @orders
  • Run cross-module scenarios: cucumber --tags "@orders and @payments"
  • Identify module dependencies clearly

9.9 Module Size Guidelines

Healthy module size:

  • 3-10 features per module
  • Each feature: 5-15 rules
  • Each rule: 2-5 scenarios

Warning signs of poor modularization:

Module too small:

payments/
└── collect_payment.feature  # Only 1 feature

Solution: Merge with related module or identify missing features

Module too large:

orders/
├── place_order.feature
├── approve_order.feature
├── cancel_order.feature
├── modify_order.feature
├── track_order.feature
├── archive_order.feature
├── export_order.feature
├── print_order.feature
├── email_order.feature
├── import_order.feature
└── validate_order.feature  # 11 features - too many!

Solution: Split into sub-modules or bounded contexts

9.10 Real-World Module Structure Example

Sales Force Automation System:

features/
├── orders/
│   ├── README.md
│   ├── place_order.feature
│   ├── approve_credit_order.feature
│   └── cancel_order.feature
├── payments/
│   ├── README.md
│   ├── collect_payment.feature
│   ├── process_refund.feature
│   └── verify_mpesa_payment.feature
├── customers/
│   ├── README.md
│   ├── register_customer.feature
│   ├── update_customer_details.feature
│   └── manage_credit_limit.feature
├── inventory/
│   ├── README.md
│   ├── adjust_stock.feature
│   ├── transfer_stock.feature
│   └── perform_stocktake.feature
├── route_planning/
│   ├── README.md
│   ├── plan_daily_route.feature
│   └── optimize_route.feature
├── visits/
│   ├── README.md
│   ├── check_in_at_customer.feature
│   └── record_visit_outcome.feature
└── pricing/
    ├── README.md
    ├── manage_price_lists.feature
    ├── apply_special_prices.feature
    └── configure_blanket_agreements.feature

9.11 Running Tests by Module

Run entire module:

cucumber features/orders

Run specific feature in module:

cucumber features/orders/place_order.feature

Run smoke tests across all modules:

cucumber --tags @smoke

Run specific module's smoke tests:

cucumber features/orders --tags @smoke

Run cross-module integration tests:

cucumber --tags "@orders and @payments"

9.12 Module Ownership

Assign ownership to teams:

# CODEOWNERS
features/orders/          @sales-team
features/payments/        @finance-team
features/inventory/       @warehouse-team
features/route_planning/  @logistics-team

Benefits:

  • Clear responsibility for feature quality
  • Teams can evolve their modules independently
  • Easier to review changes
  • Natural alignment with team structure

9.13 Module Evolution

Adding new features to existing modules:

  1. Check if feature fits module's purpose
  2. Review related features for consistency
  3. Update module README.md
  4. Add cross-references where needed

Creating new modules:

Only create a new module when:

  • ✅ Represents a distinct business domain
  • ✅ Has 3+ related features
  • ✅ Has different stakeholders than existing modules
  • ✅ Can evolve independently

Don't create a new module when:

  • ❌ Only 1-2 features
  • ❌ Closely coupled to existing module
  • ❌ Just a technical subdivision

9.14 Module Anti-Patterns

Anti-Pattern 1: Technical Modules

# ❌ Bad - organized by technical layer
features/
├── api/
├── ui/
└── database/

Solution: Organize by business domain, use tags for technical concerns

Anti-Pattern 2: Over-Modularization

# ❌ Bad - too granular
features/
├── order_creation/
├── order_validation/
├── order_pricing/
└── order_submission/

Solution: Combine into orders/ module

Anti-Pattern 3: God Module

# ❌ Bad - everything in one module
features/
└── application/
    ├── place_order.feature
    ├── collect_payment.feature
    ├── register_customer.feature
    ├── adjust_stock.feature
    └── ... 50 more features

Solution: Split into domain-specific modules

Anti-Pattern 4: Duplicate Features Across Modules

# ❌ Bad - same feature in multiple modules
features/
├── orders/
│   └── place_order.feature
└── sales/
    └── place_order.feature  # Duplicate!

Solution: Feature belongs in ONE module, use tags for cross-cutting concerns

9.15 Module Documentation Template

# [Module Name]

## Purpose
[One sentence describing the module's business purpose]

## Features
- **[Feature 1]** - [Brief description]
- **[Feature 2]** - [Brief description]
- **[Feature 3]** - [Brief description]

## Key Business Rules
- [Major rule 1]
- [Major rule 2]
- [Major rule 3]

## Stakeholders
- [Primary user role]
- [Secondary user role]

## Related Modules
- **[Module]** - [How they relate]
- **[Module]** - [How they relate]

## Dependencies
- [External system or API if applicable]

## Running Tests
```bash
# All features
cucumber features/[module]

# Smoke tests
cucumber features/[module] --tags @smoke

# Critical scenarios
cucumber features/[module] --tags @critical

Recent Changes

  • [Date] - [Change description]

---

## 10. Language and Vocabulary

### 8.1 Ubiquitous Language

Use **one term for one concept** consistently across all features.

Create a domain glossary and enforce it:

**Example Domain Terms:**
- **Sales representative** (not agent, user, rep, salesperson)
- **Place an order** (not submit, create, send, save)
- **Route plan** (not schedule, itinerary, route)
- **Customer** (not client, account, buyer)
- **Credit order** (not invoice, on-account order)

### 8.2 Business Language Only

**Never use:**
- Technical terminology
- Implementation details
- UI element names
- API endpoints
- Database concepts
- Service names
- Framework terms

**Always use:**
- Domain concepts
- Business processes
- User roles
- Business outcomes
- Policy terms

### 8.3 Language Test

Ask: **"Would a non-technical stakeholder understand this sentence?"**

If no → rewrite in business language.

**Technical (wrong):**
```gherkin
When the POST request to /api/orders is processed
Then the response status is 201
And the order_id is returned in the JSON payload

Business (right):

When the order is placed
Then the order is submitted successfully

8.4 Avoiding Ambiguity

Be specific about business terms:

Vague:

Given the order is valid
When it is processed
Then it succeeds

Specific:

Given customer "Acme Store" is within their credit limit of 10000.00
When a credit order totaling 5000.00 is placed
Then the order is submitted successfully

9. Common Anti-Patterns

9.1 Feature Sprawl

Problem: Creating features for every minor variation

Example:

# ❌ These should all be one feature
Feature: Add product to order
Feature: Remove product from order
Feature: Update order quantity
Feature: Change order UOM

Solution: One feature with rules and scenarios

Feature: Place an order
  Rule: An order consists of one or more order items
    Scenario: The one where a product is added to the order
    Scenario: The one where the same product is added multiple times
    Scenario: The one where an order has no items

9.2 Permission/Config as Features

Problem: Treating permissions or configuration as capabilities

Example:

# ❌ Not features
Feature: User can place orders
Feature: Enable discounts
Feature: Require approval

Solution: Rules within the actual feature

Feature: Place an order
  Rule: Only authorized users may place orders
  Rule: Discounts may only be applied when allowed by the business
  Rule: Credit orders must satisfy credit and approval policies

9.3 Technical Gherkin

Problem: Exposing implementation in scenarios

Example:

# ❌ Technical language
Scenario: POST /api/orders returns 201
  Given the OrderService is configured
  When the HTTP POST request is sent
  Then the database transaction commits
  And the response JSON contains order_id

Solution: Business language

Scenario: The one where an order is submitted successfully
  Given a sales representative has added products to an order
  When the order is placed
  Then the order is submitted successfully

9.4 UI Testing in Disguise

Problem: Testing UI instead of business behavior

Example:

# ❌ UI-focused
Scenario: Order form validation
  Given the user is on the order page
  When the Submit button is clicked without entering products
  Then an error message appears
  And the button is disabled

Solution: Business behavior

Scenario: The one where an empty order cannot be submitted
  Given a sales representative is placing an order
  And no products have been added
  When the order is submitted
  Then the order is rejected

9.5 Tautological Rules

Problem: Rules that just restate the feature

Example:

# ❌ Meaningless rules
Rule: An order must be valid
Rule: The system must work correctly
Rule: All business rules must be satisfied

Solution: Specific, meaningful rules

Rule: An order consists of one or more order items
Rule: Orders may only be placed for customers in the active route plan
Rule: Credit orders must satisfy credit and approval policies

9.6 Exhaustive Permutations

Problem: Creating scenarios for every possible combination

Example:

# ❌ Excessive permutations
Scenario: Cash order with 1 item
Scenario: Cash order with 2 items
Scenario: Cash order with 3 items
Scenario: Credit order with 1 item
Scenario: Credit order with 2 items
# ... and so on

Solution: Meaningful examples covering distinct behaviors

Scenario: The one where a product is added to the order
Scenario: The one where the same product is added multiple times
Scenario: The one where credit is within the allowed limit

9.7 Implementation Leakage

Problem: Revealing system internals in feature files

Example:

# ❌ Implementation details exposed
Rule: Orders are validated using the OrderValidator class
Scenario: The one where the order passes validation
  Given an Order entity with valid properties
  When the validate() method is called
  Then no ValidationException is thrown

Solution: Business concepts only

Rule: An order consists of one or more order items
Scenario: The one where an empty order cannot be submitted
  Given a sales representative is placing an order
  And no products have been added
  When the order is submitted
  Then the order is rejected

9.8 Vague Scenarios

Problem: Using abstract terms instead of concrete examples

Example:

# ❌ Vague and abstract
Scenario: The one where pricing is applied correctly
  Given a customer with special pricing
  When a product is added
  Then the correct price is used

Solution: Specific, concrete examples

Scenario: The one where special price applies
  Given customer "Acme Store" has special price for "Coca Cola 500ml" carton at 92.00 with minimum 5 cartons
  And standard price is 95.00 per carton
  When "Coca Cola 500ml" with quantity 5 cartons is added
  Then the selling price is 92.00 per carton

10. Case Study: Cart Management

This case study demonstrates how to apply the standard when distinguishing features from behaviors.

10.1 The Question

Should we create separate features for:

  • Add to cart
  • Remove from cart
  • Update cart item

Or one unified feature?

10.2 Apply the Feature Test

Ask: "Does this represent a business capability that delivers value on its own?"

CandidateFeature?Reason
Add to cartState mutation only
Remove from cartCorrective action
Update cart itemTechnical phrasing
Manage a cartBusiness capability

10.3 Why "Manage a Cart" Is the Feature

Users think:

  • "I'm building an order"
  • "I'm adjusting what I want to buy"

They don't think in API operations.

The cart is the business concept. Add/remove/update are behaviors within that capability.

10.4 Correct Cart Feature

Feature: Manage a cart
  In order to prepare an order before submission
  As a sales representative
  I need to manage the items in my cart

  Rule: Items can be added to the cart
    
    Scenario: The one where a product is added to an empty cart
      Given a sales representative with an empty cart
      When "Coca Cola 500ml" with quantity 5 cartons is added to the cart
      Then the cart contains "Coca Cola 500ml" with quantity 5 cartons
    
    Scenario: The one where the same product is added twice
      Given a cart contains "Coca Cola 500ml" with quantity 5 cartons
      When "Coca Cola 500ml" with quantity 3 cartons is added again
      Then the cart contains "Coca Cola 500ml" with quantity 8 cartons

  Rule: Items can be removed from the cart
    
    Scenario: The one where a product is removed
      Given a cart contains "Coca Cola 500ml" with quantity 5 cartons
      When "Coca Cola 500ml" is removed from the cart
      Then the cart no longer contains "Coca Cola 500ml"

  Rule: Item quantities can be adjusted
    
    Scenario: The one where quantity is increased
      Given a cart contains "Coca Cola 500ml" with quantity 5 cartons
      When the quantity is changed to 10 cartons
      Then the cart contains "Coca Cola 500ml" with quantity 10 cartons

10.5 When Separate Features Are Valid

Create separate features only when the action is itself a distinct business capability:

Valid Separate FeatureWhy
Convert cart to orderDistinct outcome
Save cart as draftPersisted business intent
Share cart for approvalCross-role capability

10.6 The Cart-to-Order Relationship

Note that "Manage a cart" and "Place an order" are separate features because:

  • Managing a cart is about preparation and exploration
  • Placing an order is about commitment and recording a transaction

The cart is temporary and can be abandoned. The order is permanent and has business consequences.

This distinction matters to the business, so they are separate features.


11. Complete Example

Here's a full feature file demonstrating all principles with specific, concrete scenarios:

Feature: Place an order
  In order to sell products to customers
  As a sales representative
  I need to place an order for a customer

  # Order item construction

  Rule: An order consists of one or more order items

    Scenario: The one where a product is added to an empty order
      Given a sales representative is placing an order for customer "Acme Store"
      When "Coca Cola 500ml" with quantity 10 cartons is added to the order
      Then the order contains "Coca Cola 500ml" with quantity 10 cartons

    Scenario: The one where the same product and batch is added twice
      Given an order contains "Coca Cola 500ml" batch "B123" with quantity 5 cartons
      When "Coca Cola 500ml" batch "B123" with quantity 3 cartons is added again
      Then the order contains "Coca Cola 500ml" batch "B123" with quantity 8 cartons

    Scenario: The one where an empty order cannot be submitted
      Given a sales representative is placing an order
      And no products have been added
      When the order is submitted
      Then the order is rejected

  # Automatic pricing

  Rule: Product prices are determined by price list hierarchy

    Scenario: The one where customer group price list overrides user price list
      Given the sales representative has price list "Standard Wholesale" with price 95.00
      And customer "Acme Store" belongs to group "Premium Retailers" with price list "Premium"
      And "Coca Cola 500ml" carton costs 90.00 on "Premium"
      When "Coca Cola 500ml" with quantity 1 carton is added
      Then the selling price is 90.00 per carton

    Scenario: The one where price changes when UOM changes
      Given "Coca Cola 500ml" has prices: pieces at 10.00, cartons at 95.00
      And an order contains "Coca Cola 500ml" with quantity 1 carton at 95.00
      When the UOM is changed to pieces with quantity 10
      Then the selling price is 10.00 per piece

  # Special prices and blanket agreements

  Rule: Blanket agreements take highest priority in pricing

    Scenario: The one where blanket agreement price is applied
      Given customer "Acme Store" has blanket agreement "BA-2024-001" for "Coca Cola 500ml" carton at 88.00
      And the blanket agreement has remaining balance of 100 cartons
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the selling price is 88.00 per carton
      And blanket agreement "BA-2024-001" is recorded on the order item

  Rule: Special prices apply when minimum quantity is met

    Scenario: The one where special price applies
      Given customer "Acme Store" has special price for "Coca Cola 500ml" carton at 92.00 with minimum 5 cartons
      And standard price is 95.00 per carton
      When "Coca Cola 500ml" with quantity 5 cartons is added
      Then the selling price is 92.00 per carton

    Scenario: The one where volume discount applies
      Given customer "Acme Store" has volume discounts for "Coca Cola 500ml":
        | Minimum Quantity | Price |
        | 10               | 92.00 |
        | 20               | 90.00 |
        | 50               | 87.00 |
      When "Coca Cola 500ml" with quantity 25 cartons is added
      Then the selling price is 90.00 per carton

  # Promotions

  Rule: Promotions are applied automatically to qualifying orders

    Scenario: The one where percentage discount promotion applies
      Given a promotion offers 10% discount on "Coca Cola 500ml" with minimum 10 cartons
      And standard price is 95.00 per carton
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the selling price is 85.50 per carton
      And promotion type is "Percentage Discount"

    Scenario: The one where free product promotion applies
      Given a promotion offers 2 free pieces for every 10 cartons of "Coca Cola 500ml"
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the order contains "Coca Cola 500ml" 10 cartons at standard price
      And the order contains "Coca Cola 500ml" 2 pieces at 0.00
      And the free items have promotion type "Free Product"

    Scenario: The one where promotions do not apply to blanket priced items
      Given customer has blanket agreement for "Coca Cola 500ml" at 88.00
      And a promotion offers 10% discount on "Coca Cola 500ml"
      And promotion override is not allowed
      When "Coca Cola 500ml" with quantity 10 cartons is added
      Then the selling price is 88.00 per carton
      And no promotion is applied

  # Stock validation

  Rule: Stock must be sufficient for sales and samples

    Scenario: The one where stock is insufficient
      Given "Coca Cola 500ml" batch "B123" has 5 cartons in stock
      When "Coca Cola 500ml" batch "B123" with quantity 10 cartons is added to a sale
      Then the item is rejected due to insufficient stock

    Scenario: The one where adding to existing quantity exceeds stock
      Given "Coca Cola 500ml" batch "B123" has 50 cartons in stock
      And the order already contains "Coca Cola 500ml" batch "B123" with 45 cartons
      When "Coca Cola 500ml" batch "B123" with quantity 10 cartons is added
      Then the item is rejected due to insufficient stock

  # Route plan constraints

  Rule: Orders may only be placed for customers in the active route plan

    Scenario: The one where customer is in route plan
      Given customer "Acme Store" is in today's active route plan
      When the order is placed
      Then the order is submitted successfully

    Scenario: The one where customer is not in route plan
      Given customer "Acme Store" is not in today's active route plan
      When the order is placed
      Then the order is rejected

  # Permissions

  Rule: Only authorized users may place orders

    Scenario: The one where user has permission
      Given the sales representative has "place orders" permission
      When the order is placed
      Then the order is submitted successfully

    Scenario: The one where user lacks permission
      Given the sales representative does not have "place orders" permission
      When the order is placed
      Then the order is rejected

  # Credit and approvals

  Rule: Credit limits must be respected

    Scenario: The one where credit is within limit
      Given customer "Acme Store" has credit limit of 10000.00
      And current balance is 3000.00
      When a credit order totaling 5000.00 is placed
      Then the order is submitted successfully

    Scenario: The one where credit exceeds limit
      Given customer "Acme Store" has credit limit of 10000.00
      And current balance is 8000.00
      When a credit order totaling 5000.00 is placed
      Then the order is rejected
      And the error message indicates credit limit exceeded

    Scenario: The one where discount approval is required
      Given discount approval is required
      And customer discounts totaling 500.00 have been applied
      When the order is submitted
      Then the order status is "Pending"
      And discount status is "Pending"

12. Quality Checklist

Use this checklist before merging any feature file.

Feature-Level Checks

  • Represents a real, distinct business capability
  • Can be explained without referencing another feature
  • Uses business language exclusively
  • Intent block is clear and unconditional
  • Would be meaningful if removed
  • Name uses active verb (e.g., "Place an order" not "Order placement")

Rule-Level Checks

  • All constraints are expressed as Rules
  • Rules describe what, not how
  • Rules are evaluated at the same decision point as the action
  • No duplication of rules across features
  • No tautological or meaningless rules
  • Each rule adds distinct business meaning
  • Rules use declarative language

Scenario-Level Checks

  • One behavior per scenario
  • Friends episode notation used consistently
  • Given establishes context with specific values
  • When describes exactly one action with concrete details
  • Then describes observable outcome with measurable results
  • No technical or UI language
  • Scenarios are independent
  • Can be understood by non-technical stakeholders
  • Scenario name clearly indicates what happens
  • No vague terms - uses actual product names, quantities, prices
  • No abstract descriptions - uses concrete business examples

Specificity Checks

  • Product names are real (not "a product" or "product X")
  • Quantities are specified (not "some quantity" or "multiple items")
  • Prices are exact (not "the correct price" or "appropriate amount")
  • Customer names are concrete (not "a customer" or "the user")
  • Error messages are quoted exactly
  • Batch numbers, order IDs, and references are specific
  • Dates and times are concrete when relevant

Coverage Checks

  • Positive cases documented
  • Negative cases documented
  • Configuration variants shown as scenarios
  • Permissions modeled as rules
  • Approvals modeled as rules
  • Ubiquitous language used consistently
  • Edge cases covered without exhaustive permutations

Documentation Quality

  • Non-technical stakeholders can read and understand
  • Developers can implement from the specification
  • Testers can verify behavior
  • Product owners can validate requirements
  • No ambiguity in expected behavior
  • Comments (if any) only clarify organization, not behavior

13. Getting Started

13.1 For New Projects

  1. Identify your core business capabilities — what can users actually do?
  2. Create one feature file per capability — start with the most important
  3. Document the happy path first — get agreement on success
  4. Add constraints as rules — identify what can go wrong
  5. Demonstrate with specific scenarios — provide concrete examples with real values
  6. Review with stakeholders — ensure everyone understands
  7. Refine vocabulary — establish ubiquitous language

13.2 For Existing Projects

  1. Audit existing documentation — identify features vs rules vs technical tests
  2. Consolidate related features — reduce sprawl
  3. Extract rules from conditional logic — make policies explicit
  4. Rewrite in business language — remove technical terminology
  5. Make scenarios concrete — replace vague terms with specific examples
  6. Align with domain experts — validate understanding
  7. Establish standards — use this guide
  8. Migrate gradually — improve one feature at a time

13.3 Building Team Alignment

  • Run workshops with mixed teams (business + technical)
  • Review features together before implementation
  • Use features in planning — estimate from scenarios
  • Reference scenarios in code — maintain traceability
  • Update features when requirements change — keep documentation living
  • Celebrate good examples — recognize quality documentation
  • Practice specificity — challenge vague scenarios in reviews

14. Summary

Living documentation with BDD features succeeds when you:

  1. Model capabilities, not implementations
  2. Use business language exclusively
  3. Organize with Features → Rules → Scenarios
  4. Demonstrate rules with concrete, specific examples
  5. Use real values, not abstract placeholders
  6. Maintain consistency across all features
  7. Keep documentation close to reality

This isn't just about writing better tests—it's about creating a shared understanding that bridges business and technology, remains accurate over time, and serves as the definitive source of truth for what your system does.

Key Principles to Remember:

Features = capabilities
Rules = constraints
Scenarios = concrete examples with specific values

Consistency matters more than perfection.

When in doubt, ask:

  • Is this a capability or a constraint?
  • Would a non-technical person understand this?
  • Does this describe what the business needs or how we build it?
  • Am I being specific enough? (Real names, actual quantities, exact prices)
  • Could someone implement/test this from my description alone?

Follow these principles, and your feature files will serve as true living documentation that everyone can understand, trust, and use.

On this page

Living Documentation with BDD Features: A Comprehensive GuideTable of Contents1. Introduction1.1 What Is Living Documentation?1.2 Why BDD Features?1.3 Who Should Read This?2. Core Philosophy2.1 Three Fundamental Principles2.2 Business-First Thinking2.3 Who Are We Writing For?3. The Feature Structure3.1 Mandatory Components3.2 Gherkin 6 Syntax3.3 Component Hierarchy4. Features vs Rules vs Scenarios4.1 What Is a Feature?4.2 What Is a Rule?4.3 What Is a Scenario?5. Writing Features5.1 The Feature Intent Block5.2 Identifying Real Features5.3 Feature Granularity5.4 When Configuration Isn't a Feature6. Writing Rules6.1 Rule Purpose6.2 Rule Formatting6.3 Good Rule Examples6.4 Bad Rule Examples6.5 When to Create a New Rule6.6 Rule Organization7. Writing Scenarios7.1 Scenario Purpose7.2 The Friends Episode Notation (Mandatory)7.3 Given-When-Then StructureGiven: ContextWhen: ActionThen: Outcome7.4 Writing Specific, Not Vague Scenarios7.5 One Behavior Per Scenario7.6 Scenario Independence7.7 Positive and Negative Cases7.8 Configuration Variants7.9 When to Use Scenario Outlines8. Using Tags8.1 What Are Tags?8.2 Tag Placement Rules8.3 Standard Tag Categories8.3.1 Test Execution Tags8.3.2 Business Domain Tags8.3.3 Priority and Risk Tags8.3.4 Technical Characteristic Tags8.3.5 Configuration and Environment Tags8.3.6 Platform and Channel Tags8.4 Tag Naming Conventions8.5 Practical Tagging Strategies8.5.1 Smoke Test Suite8.5.2 Progressive Test Execution8.5.3 Feature Flag Management8.5.4 Component-Based Organization8.5.5 Cross-Platform Behavior8.5.6 Platform-Specific Behavior8.6 Tag Combination with Boolean Logic8.7 Tags to Avoid8.8 Documenting Tag Strategy8.11 Tag Minimalism: Avoiding Tag Overload8.11.1 The Minimalism Principle8.11.2 Tag Inheritance Strategy8.11.3 Choose Your Tag Strategy8.11.4 The Three-Tag Rule8.11.5 Tag Consolidation Strategies8.11.6 When to Use Each Tag Type8.11.7 Tag Audit Checklist8.11.8 Real-World Example: Progressive Refinement8.11.9 Team Agreement Template8.11.10 The Golden Rules of Tagging9. Organizing Features into Modules9.1 What Are Modules?9.2 Module vs Feature vs Rule9.3 Identifying Modules9.4 File Structure for Modules9.5 Naming Conventions for Module Files9.6 Module Documentation9.8 Module Tagging Strategy9.9 Module Size Guidelines9.10 Real-World Module Structure Example9.11 Running Tests by Module9.12 Module Ownership9.13 Module Evolution9.14 Module Anti-Patterns9.15 Module Documentation TemplateRecent Changes8.4 Avoiding Ambiguity9. Common Anti-Patterns9.1 Feature Sprawl9.2 Permission/Config as Features9.3 Technical Gherkin9.4 UI Testing in Disguise9.5 Tautological Rules9.6 Exhaustive Permutations9.7 Implementation Leakage9.8 Vague Scenarios10. Case Study: Cart Management10.1 The Question10.2 Apply the Feature Test10.3 Why "Manage a Cart" Is the Feature10.4 Correct Cart Feature10.5 When Separate Features Are Valid10.6 The Cart-to-Order Relationship11. Complete Example12. Quality ChecklistFeature-Level ChecksRule-Level ChecksScenario-Level ChecksSpecificity ChecksCoverage ChecksDocumentation Quality13. Getting Started13.1 For New Projects13.2 For Existing Projects13.3 Building Team Alignment14. Summary