Lesson 10: Behaviour-Driven Development
Learning Objectives
By the end of this lesson, you will be able to:
- Explain the BDD philosophy and how it differs from traditional test-driven development by focusing on behavior rather than implementation
- Apply the Given-When-Then format to write clear, unambiguous specifications that both technical and non-technical stakeholders understand
- Facilitate BDD collaboration through example mapping, three amigos sessions, and structured conversations that build shared understanding
- Create executable specifications that serve as both documentation and automated tests using BDD frameworks
- Integrate BDD into development workflows to bridge the gap between business requirements and technical implementation
Introduction
Behaviour-Driven Development (BDD) emerged from test-driven development with a crucial insight: the language we use to describe software shapes how we think about it and build it. While TDD focuses on testing implementation, BDD focuses on specifying behavior from a user’s perspective. This subtle shift transforms how teams collaborate, communicate, and deliver software [1].
Traditional requirements documents often suffer from ambiguity—business stakeholders and developers interpret the same requirements differently, leading to expensive misunderstandings discovered late in development. BDD addresses this by using concrete examples written in structured natural language that both business people and developers can understand and verify. These examples become executable specifications that validate the system behaves as intended [2].
The power of BDD lies in collaboration. Rather than analysts writing requirements that developers implement and testers verify in isolation, BDD brings these perspectives together early. The “three amigos”—a business representative, a developer, and a tester—collaboratively explore requirements through conversation, discovering ambiguities and edge cases before any code is written. This shared understanding dramatically reduces rework and ensures everyone works toward the same goal [3].
BDD also creates living documentation—specifications that stay synchronized with code because they’re executable tests. Unlike static documents that become outdated, BDD scenarios remain accurate because they fail when behavior changes. This provides confidence that documentation reflects reality and serves as a complete specification of system behavior [4].
Core Content
The BDD Philosophy: Behavior Over Implementation
BDD represents a fundamental shift in how we think about software development. Instead of asking “how should I test this?”, BDD asks “what behavior should this system exhibit?” [1].
Key Principles of BDD:
Outside-In Development: Start with external behavior (what users experience) and work inward to implementation. This ensures you build what users actually need.
Ubiquitous Language: Use domain language that business stakeholders understand. Avoid technical jargon in specifications.
Concrete Examples: Replace abstract requirements with specific examples that illustrate desired behavior.
Collaboration: Bring together different perspectives—business, development, testing—to build shared understanding.
Living Documentation: Specifications serve as both documentation and automated tests, staying synchronized with code.
BDD vs TDD:
While related, BDD and TDD have different focus:
TDD (Test-Driven Development):
- Focus: Implementation correctness
- Language: Technical (code-level tests)
- Audience: Developers
- Questions: "How do I test this?" "Does it work?"
Example TDD Test:
def test_discount_calculation():
cart = ShoppingCart()
cart.add_item(price=100)
discount = cart.calculate_discount(customer_tier='gold')
assert discount == 20 # 20% for gold tier
BDD (Behaviour-Driven Development):
- Focus: Business behavior
- Language: Domain terms (scenarios)
- Audience: Everyone (business, dev, test)
- Questions: "What should it do?" "Why does it matter?"
Example BDD Scenario:
Scenario: Gold tier customers receive 20% discount
Given I am a gold tier customer
And I have a cart with items worth $100
When I proceed to checkout
Then I should receive a $20 discount
And my total should be $80The Given-When-Then Format
Given-When-Then is the standard structure for BDD scenarios. It provides a template that’s both rigorous and readable [2].
Structure:
- Given: Context/preconditions - the state of the world before the scenario begins
- When: Action/event - what happens to trigger the behavior
- Then: Outcome/postconditions - the expected result
Basic Example:
Scenario: Successful user login
Given a user exists with email "[email protected]" and password "ValidPass123"
And the user is on the login page
When the user enters email "[email protected]"
And the user enters password "ValidPass123"
And the user clicks the "Log In" button
Then the user should see the dashboard
And the user should see a welcome message "Welcome back!"Multiple Given/When/Then Clauses:
Use “And” to add additional conditions or actions:
Scenario: Calculate shipping for multiple items
Given I am logged in as a customer
And I have added a "Laptop" priced at $999 to my cart
And I have added a "Mouse" priced at $29 to my cart
And I have selected "Express Shipping"
When I proceed to checkout
Then I should see a subtotal of $1,028
And I should see a shipping charge of $25
And I should see a total of $1,053But for Negative Conditions:
Use “But” for readability when expressing negative conditions:
Scenario: Insufficient inventory prevents order
Given a product "Limited Edition Widget" has 2 units in stock
When a customer attempts to order 5 units
Then the order should be rejected
And the customer should see an error "Insufficient inventory"
But the product should still show 2 units in stockFocusing on Behavior, Not Implementation:
# Bad - Too implementation-focused
Scenario: User authentication
Given the user database contains a record with ID 123
When the AuthService.authenticate() method is called
Then the JWT token generation service should be invoked
And a token with user_id=123 should be returned
# Good - Behavior-focused
Scenario: User successfully logs in
Given I am a registered user
When I log in with valid credentials
Then I should have access to my account
And I should see my personalized dashboardConcrete Examples vs Abstract Descriptions:
# Bad - Abstract
Scenario: Products with high prices get discounts
Given expensive products exist
When a customer purchases them
Then appropriate discounts should apply
# Good - Concrete
Scenario: Products over $100 receive 10% discount
Given a product "Premium Widget" is priced at $150
When I add it to my cart
Then I should see a discount of $15
And the final price should be $135The BDD Workflow: Three Amigos and Example Mapping
BDD emphasizes collaboration through structured conversations that happen before implementation begins [3].
The Three Amigos:
Bring together three perspectives:
- Business/Product: Understands what needs to be built and why
- Development: Understands technical possibilities and constraints
- Testing: Understands edge cases, failure modes, and quality concerns
Three Amigos Session Structure:
1. Review the User Story (5 minutes)
- Product owner presents the story and acceptance criteria
- Team asks clarifying questions
2. Explore with Examples (20-30 minutes)
- Generate concrete examples of the feature in action
- Identify rules and edge cases
- Use example mapping technique
3. Document Scenarios (10 minutes)
- Convert examples into Given-When-Then scenarios
- Identify questions that need answering
- Assign action items
4. Review and Confirm (5 minutes)
- Confirm shared understanding
- Identify scenarios ready for implementationExample Mapping:
Example mapping uses index cards to visualize the conversation:
[User Story Card - Yellow]
As a customer, I want to apply discount codes
so that I can save money on purchases
[Rule Cards - Blue]
┌─────────────────────────┐ ┌─────────────────────────┐
│ Rule: Valid codes │ │ Rule: One code per order│
│ reduce total price │ │ │
└─────────────────────────┘ └─────────────────────────┘
[Example Cards - Green]
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ 10% off code │ │ Expired code fails │ │ Invalid code fails │
│ $100 cart → $90 │ │ Shows error message │ │ Shows error message │
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
[Question Cards - Red]
┌────────────────────────────────────────┐
│ Can codes be combined? │
│ What if code exceeds cart total? │
└────────────────────────────────────────┘Benefits of Example Mapping:
- Visual: See progress and coverage at a glance
- Focused: Keeps conversation on track
- Collaborative: Everyone contributes equally
- Action-oriented: Red cards become questions to resolve
Conversation Example:
Product Owner: "Users should be able to apply discount codes."
Developer: "What happens if they enter an invalid code?"
Tester: "And what if the code has expired?"
Product Owner: "Good questions. Invalid codes should show an error
message but keep their cart. Expired codes should also
show an error with the expiration date."
Developer: "Can users apply multiple codes?"
Product Owner: "No, only one code per order."
Tester: "What if the discount exceeds the cart total? Say they have a
$20 code but only $15 in their cart?"
Product Owner: "Hmm, I'll need to check with management. Let's mark
that as a red card question."This conversation generates concrete scenarios:
Scenario: Apply valid discount code
Given I have items totaling $100 in my cart
When I apply discount code "SAVE10" for 10% off
Then my cart total should be $90
And I should see "Discount code SAVE10 applied"
Scenario: Invalid discount code shows error
Given I have items in my cart
When I apply discount code "INVALID"
Then I should see an error "Invalid discount code"
And my cart total should remain unchanged
Scenario: Expired discount code shows error
Given discount code "EXPIRED" expired on January 1, 2025
And today is January 15, 2025
When I attempt to apply code "EXPIRED"
Then I should see an error "Code expired on January 1, 2025"
Scenario: Only one discount code per order
Given I have items totaling $100 in my cart
And I have applied discount code "SAVE10" for 10% off
When I attempt to apply another code "SAVE20"
Then I should see "Only one discount code allowed per order"
And only "SAVE10" should be appliedImplementing BDD with Frameworks
BDD scenarios become executable specifications using frameworks like Cucumber, Behave (Python), or SpecFlow (.NET) [4].
Behave (Python) Example:
Feature File (features/discount_codes.feature):
Feature: Discount Codes
As a customer
I want to apply discount codes
So that I can save money on purchases
Background:
Given I am a registered customer
And I have the following items in my cart:
| product | price |
| Widget A | $50 |
| Widget B | $50 |
Scenario: Apply percentage discount code
When I apply discount code "SAVE10"
Then my subtotal should be $100
And my discount should be $10
And my total should be $90
Scenario: Apply fixed amount discount code
Given a discount code "FIXED20" for $20 off
When I apply discount code "FIXED20"
Then my subtotal should be $100
And my discount should be $20
And my total should be $80
Scenario Outline: Invalid codes show appropriate errors
When I apply discount code "<code>"
Then I should see error "<error_message>"
And my total should be $100
Examples:
| code | error_message |
| INVALID | Invalid discount code |
| EXPIRED | This code has expired |
| USED | This code has already been used |Step Definitions (features/steps/discount_steps.py):
from behave import given, when, then, step
from decimal import Decimal
@given('I am a registered customer')
def step_impl(context):
context.customer = create_test_customer()
@given('I have the following items in my cart')
def step_impl(context):
context.cart = ShoppingCart(context.customer)
for row in context.table:
product_name = row['product']
price = Decimal(row['price'].replace('$', ''))
context.cart.add_item(product_name, price)
@given('a discount code "{code}" for ${amount:d} off')
def step_impl(context, code, amount):
create_discount_code(
code=code,
type='fixed',
amount=Decimal(amount)
)
@when('I apply discount code "{code}"')
def step_impl(context, code):
context.result = context.cart.apply_discount_code(code)
@then('my subtotal should be ${amount:d}')
def step_impl(context, amount):
assert context.cart.subtotal == Decimal(amount), \
f"Expected subtotal ${amount}, got ${context.cart.subtotal}"
@then('my discount should be ${amount:d}')
def step_impl(context, amount):
assert context.cart.discount == Decimal(amount), \
f"Expected discount ${amount}, got ${context.cart.discount}"
@then('my total should be ${amount:d}')
def step_impl(context, amount):
expected = Decimal(amount)
actual = context.cart.total
assert actual == expected, \
f"Expected total ${expected}, got ${actual}"
@then('I should see error "{error_message}"')
def step_impl(context, error_message):
assert context.result['success'] is False
assert error_message in context.result['error'], \
f"Expected error containing '{error_message}', got '{context.result['error']}'"Running BDD Tests:
# Run all scenarios
behave
# Run specific feature
behave features/discount_codes.feature
# Run scenarios with specific tag
behave --tags=@critical
# Generate HTML report
behave -f html -o reports/bdd_report.html
# Output:
Feature: Discount Codes # features/discount_codes.feature:1
As a customer
I want to apply discount codes
So that I can save money on purchases
Background:
Given I am a registered customer ... passed
And I have the following items in my cart ... passed
Scenario: Apply percentage discount code
When I apply discount code "SAVE10" ... passed
Then my subtotal should be $100 ... passed
And my discount should be $10 ... passed
And my total should be $90 ... passed
Scenario: Apply fixed amount discount code
Given a discount code "FIXED20" for $20 off ... passed
When I apply discount code "FIXED20" ... passed
Then my subtotal should be $100 ... passed
And my discount should be $20 ... passed
And my total should be $80 ... passed
Scenario Outline: Invalid codes show appropriate errors
| code | error_message |
| INVALID | Invalid discount code | passed
| EXPIRED | This code has expired | passed
| USED | This code has already been used| passed
3 features passed, 0 failed, 0 skipped
10 scenarios passed, 0 failed, 0 skipped
32 steps passed, 0 failed, 0 skippedBDD as Living Documentation
BDD scenarios serve as executable documentation that stays synchronized with code [4].
Benefits of Living Documentation:
- Always Accurate: Fails when behavior changes, forcing updates
- Comprehensive: Covers all implemented behavior
- Understandable: Written in business language
- Verifiable: Can be executed to verify documentation matches reality
Documentation Structure:
features/
├── authentication/
│ ├── login.feature
│ ├── registration.feature
│ └── password_reset.feature
├── shopping/
│ ├── cart_management.feature
│ ├── checkout.feature
│ └── discount_codes.feature
└── account/
├── profile_management.feature
└── order_history.featureEach feature file documents a functional area with concrete examples.
Generated Documentation:
Many BDD tools generate human-readable documentation:
# Generate HTML documentation
behave -f html -o docs/behavior_documentation.html
# Generate Markdown documentation
behave -f markdown -o docs/features.mdDocumentation Example:
# Feature: User Authentication
## As a user, I want to log in securely
### Scenario: Successful login with valid credentials
**Given** I am a registered user with email "[email protected]"
**And** my password is "ValidPass123"
**When** I enter my email and password
**And** I click "Log In"
**Then** I should be redirected to the dashboard
**And** I should see "Welcome back!"
### Scenario: Failed login with invalid password
**Given** I am a registered user
**When** I enter my email with an incorrect password
**Then** I should see error "Invalid email or password"
**And** I should remain on the login page
**And** I should not be logged inThis documentation is generated from executable scenarios, ensuring it’s always accurate.
Common Pitfalls
Pitfall 1: Writing Implementation-Focused Scenarios
Scenarios that describe implementation details rather than behavior break when refactoring even though behavior hasn’t changed.
# Bad - Implementation details
Scenario: User login
When the AuthController.login() method receives credentials
And the PasswordHasher validates the bcrypt hash
Then a JWT token should be generated with HS256 algorithm
# Good - Behavior focus
Scenario: User logs in successfully
Given I am a registered user
When I log in with valid credentials
Then I should have access to my accountBest Practice: Write scenarios from a user’s perspective. Avoid mentioning classes, methods, databases, or technical implementation [1].
Pitfall 2: Insufficient Collaboration
Developers writing scenarios alone without business input defeats BDD’s purpose of shared understanding.
Best Practice: Require three amigos sessions for all new features. Schedule them early, before implementation begins. Product owner must approve scenarios [3].
Pitfall 3: Scenarios as Acceptance Tests Only
Using BDD only for high-level acceptance testing misses its value for guiding development and creating documentation.
Best Practice: Write scenarios at multiple levels—feature-level scenarios for acceptance, component-level scenarios for complex logic. Use BDD throughout development, not just at the end [4].
Pitfall 4: Vague or Abstract Scenarios
Abstract scenarios without concrete examples are open to interpretation, recreating the ambiguity BDD aims to eliminate.
Best Practice: Use specific, concrete examples with actual values. If the scenario seems vague, it probably needs more specific examples from the three amigos session [2].
Summary
Behaviour-Driven Development bridges the gap between business requirements and technical implementation through collaboration and concrete examples expressed in structured natural language.
The BDD philosophy focuses on behavior rather than implementation, using domain language that all stakeholders understand. Unlike TDD which tests implementation, BDD specifies behavior from the user’s perspective, creating shared understanding across business, development, and testing roles.
Given-When-Then format provides a rigorous yet readable structure for scenarios. Given establishes context, When describes the action, and Then specifies the outcome. This format forces clarity and eliminates ambiguity while remaining accessible to non-technical stakeholders.
Three amigos collaboration brings together business, development, and testing perspectives early in the development process. Through structured conversations and example mapping, teams discover edge cases, resolve ambiguities, and build shared understanding before writing code. This collaboration dramatically reduces rework and misunderstandings.
Executable specifications created with BDD frameworks like Behave or Cucumber serve dual purposes: automated tests that verify behavior and living documentation that stays synchronized with code. When scenarios fail, they highlight discrepancies between documented and actual behavior.
Living documentation generated from BDD scenarios provides comprehensive, accurate documentation that’s always up-to-date. Unlike static documents that become outdated, BDD scenarios must be maintained alongside code, ensuring documentation reflects reality.
BDD transforms development from implementation-focused activities to conversation-focused collaboration. The scenarios created aren’t just tests—they’re the shared language through which teams understand what they’re building, why it matters, and how to verify success.
Practice Quiz
Question 1: A developer writes this BDD scenario. What’s wrong with it?
Scenario: Process order
Given the OrderService has a database connection
When the create_order() method is called with valid OrderDTO
Then the OrderRepository.save() should be invoked
And the NotificationService.sendEmail() should be called
And the method should return an Order objectAnswer: This scenario violates BDD principles by focusing on implementation details rather than user behavior:
Problems:
- Mentions technical components (OrderService, OrderRepository)
- Specifies method names (create_order(), save(), sendEmail())
- References implementation concepts (DTO, database connection)
- Tests how the system works internally, not what behavior users observe
Fixed version:
Scenario: Customer successfully places an order
Given I am a logged-in customer
And I have items in my shopping cart
When I submit my order with shipping address
Then I should see an order confirmation
And I should receive an order confirmation email
And my order should appear in my order historyThis focuses on observable behavior from the user’s perspective, not implementation details. It describes what happens, not how it happens [1][2].
Question 2: Your team holds a three amigos session for a new feature: “Users should be able to filter products.” The developer immediately starts writing technical scenarios about database queries. What’s going wrong, and how should the session proceed?
Answer: The developer is jumping to implementation before understanding the behavior. Three amigos sessions should focus on what before how.
Better approach:
Facilitator (Tester): "Let's start with examples. What filtering do users need?"
Product Owner: "They should filter by category, price range, and brand."
Developer: "For price, do they enter exact amounts or select ranges?"
Product Owner: "Good question. Probably predefined ranges like 'Under $50', '$50-$100', etc."
Tester: "What if they select multiple filters? Like 'Electronics' category AND '$50-$100'?"
Product Owner: "Yes, filters should combine—show products matching all selected filters."
Developer: "So if no products match, what happens?"
Product Owner: "Show 'No products found' with option to clear filters."
Tester: "And filters should be clearable individually or all at once?"
Product Owner: "Right, individual 'X' buttons and a 'Clear All' button."Resulting scenarios:
Scenario: Filter products by single category
Given there are products in multiple categories
When I filter by "Electronics" category
Then I should see only electronics products
Scenario: Filter products by multiple criteria
Given there are products across categories and prices
When I filter by "Electronics" category
And I filter by price range "$50-$100"
Then I should see only electronics priced between $50 and $100
Scenario: No products match filter criteria
Given no products match my selected filters
Then I should see "No products found"
And I should see an option to clear filtersKey principle: Focus on user behavior and concrete examples, not database queries or technical implementation [3].
Question 3: Your BDD scenarios all pass, but users report the feature doesn’t work correctly. What might explain this, and what BDD practices would prevent it?
Answer: Several possible causes:
1. Scenarios test wrong behavior:
# Scenario tests what was built, not what was needed
Scenario: User can add items
Given I am on the product page
When I click "Add to Cart"
Then the item count increases
# But users actually need:
Scenario: User can purchase items
Given I have items in my cart
When I complete checkout with valid payment
Then I should receive my order
And my payment should be processedPrevention: Ensure product owner participates in three amigos and approves scenarios before implementation [3].
2. Insufficient coverage of edge cases:
# Only tested happy path
Scenario: Add item to cart
When I add an item
Then it appears in my cart
# Missing critical scenarios:
Scenario: Add out-of-stock item
Scenario: Add item exceeding purchase limit
Scenario: Add item to cart from different currency regionPrevention: Tester’s role in three amigos is identifying edge cases and failure modes. Use example mapping to visualize coverage [3].
3. Scenarios too high-level:
# Too vague
Scenario: Checkout works
When I checkout
Then I should complete my order
# Should be specific:
Scenario: Checkout with credit card
Given I have items totaling $100
When I enter valid credit card details
And I confirm payment
Then I should see "Order confirmed"
And my card should be charged $100
And I should receive confirmation emailPrevention: Use concrete examples with specific values. Abstract scenarios hide gaps [2].
Key BDD practice: Scenarios should specify acceptance criteria that, if all pass, mean the feature is complete and correct. If scenarios pass but feature doesn’t work, scenarios were incomplete or tested wrong behavior [4].
Question 4: Your codebase has 200 BDD scenarios that take 15 minutes to run. Developers stop running them before commits. How should you address this?
Answer: The scenario suite is too slow and likely improperly structured. BDD scenarios should follow a pyramid similar to unit/integration tests.
Solutions:
1. Separate levels of scenarios:
@unit # Fast, isolated scenarios (run constantly)
@integration # Moderate speed, with dependencies (run before push)
@e2e # Slow, full system (run in CI only)2. Tag scenarios appropriately:
@unit @critical
Scenario: Calculate discount correctly
Given cart total is $100
When 10% discount is applied
Then total should be $90
@integration
Scenario: Complete checkout process
Given logged-in user with items in cart
When user completes checkout
Then order is created and confirmation sent
@e2e @slow
Scenario: Full user journey from registration to purchase
[Long end-to-end scenario]3. Run appropriate scenarios:
# During development (seconds)
behave --tags=@unit
# Before commit (1-2 minutes)
behave --tags=@unit --tags=@integration
# In CI (full suite)
behave4. Optimize slow scenarios:
- Use test doubles for external services in lower-level scenarios
- Parallel execution:
behave --processes 4 - Background data: Set up test data once, not per scenario
Target: Unit-level scenarios in seconds, integration scenarios in 1-2 minutes, full suite in CI [4].
Question 5: Your team debates whether BDD scenarios should test internal business logic or only user-facing features. What’s the correct approach?
Answer: Both, but at different levels with different audiences.
Feature-level scenarios (user-facing):
Feature: Apply discount codes
As a customer
I want to apply discount codes
So that I can save money
Scenario: Apply valid discount code
Given I have a cart total of $100
When I apply discount code "SAVE10"
Then my total should be $90Audience: Business stakeholders, product owners Focus: User-visible behavior Language: Domain terms users understand
Component-level scenarios (business logic):
Feature: Discount calculation engine
Covers complex discount rules and edge cases
Scenario: Percentage discount on pre-tax amount
Given a cart with pre-tax total of $100
And tax rate of 10%
When a 10% discount code is applied
Then discount should be $10 (10% of $100, not $110)
And tax should be $9 (10% of $90)
And final total should be $99
Scenario: Discount capped at maximum amount
Given a cart with total of $1000
When a 50% discount code with $400 cap is applied
Then discount should be $400, not $500
And final total should be $600Audience: Developers, testers Focus: Complex business rules Language: Precise business terms
Guideline:
- Write feature-level scenarios for all user-facing functionality
- Write component-level scenarios for complex business logic, algorithms, or calculation rules
- Keep them in separate feature files organized by area
- Product owners review feature-level, developers own component-level [1][4]
References
[1] North, D. (2006). “Introducing BDD.” URL: https://dannorth.net/introducing-bdd/, Quote: “BDD is about implementing an application by describing its behavior from the perspective of its stakeholders. It focuses on obtaining a clear understanding of desired software behavior through discussion with stakeholders, using concrete examples to build shared understanding.”
[2] Adzic, G. (2011). Specification by Example: How Successful Teams Deliver the Right Software. Manning Publications. URL: https://www.manning.com/books/specification-by-example, Quote: “Key examples illustrate business rules and demonstrate expected system behavior in concrete terms that both technical and non-technical stakeholders can understand. Using concrete examples instead of abstract requirements eliminates ambiguity and provides a shared language for discussing software.”
[3] Wynne, M., & Hellesoy, A. (2017). The Cucumber Book: Behaviour-Driven Development for Testers and Developers (2nd Edition). Pragmatic Bookshelf. URL: https://pragprog.com/titles/hwcuc2/the-cucumber-book-second-edition/, Quote: “The Three Amigos meeting brings together business, development, and testing perspectives to explore requirements through conversation before implementation begins. Through example mapping and structured discussion, the team discovers edge cases, resolves ambiguities, and builds shared understanding that dramatically reduces rework.”
[4] Smart, J. F. (2014). BDD in Action: Behavior-Driven Development for the Whole Software Lifecycle. Manning Publications. URL: https://www.manning.com/books/bdd-in-action, Quote: “BDD scenarios serve as executable specifications—they’re both automated tests that verify behavior and living documentation that stays synchronized with code. When scenarios fail, they highlight discrepancies between documented and actual behavior. This living documentation provides comprehensive, accurate system documentation that’s always up-to-date.”