bdd-principles

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

BDD Principles

BDD原则

Master the foundational principles and philosophy of Behavior-Driven Development.
掌握行为驱动开发(Behavior-Driven Development,BDD)的基础原则与理念。

What is BDD?

什么是BDD?

Behavior-Driven Development (BDD) is a collaborative software development approach that:
  • Bridges the gap between business and technical teams
  • Uses concrete examples to describe system behavior
  • Creates living documentation that serves as tests
  • Focuses on delivering business value
  • Promotes shared understanding through conversation
Behavior-Driven Development(BDD)是一种协作式软件开发方法,它:
  • 弥合业务团队与技术团队之间的差距
  • 使用具体示例描述系统行为
  • 创建可作为测试的活文档
  • 专注于交付业务价值
  • 通过对话促进共识

Core Philosophy

核心理念

Discovery > Development > Delivery

发现 > 开发 > 交付

Discovery: Collaborate to understand requirements
  • Hold Three Amigos sessions
  • Explore with examples
  • Challenge assumptions
  • Build shared understanding
Development: Implement guided by examples
  • Use examples as specifications
  • Automate examples as tests
  • Follow outside-in TDD
Delivery: Validate against real behavior
  • Executable specifications provide confidence
  • Living documentation stays current
  • Regressions are caught early
发现:协作理解需求
  • 开展Three Amigos会议
  • 通过示例探索需求
  • 挑战假设
  • 建立共识
开发:以示例为指导实现功能
  • 将示例作为规格说明
  • 将示例自动化为测试
  • 遵循由外而内的TDD
交付:根据实际行为验证
  • 可执行的规格说明提供信心
  • 活文档保持最新
  • 早期发现回归问题

The Three Amigos

Three Amigos

A practice where three perspectives collaborate to explore and define features:
这是一种实践方法,由三个视角的角色协作探索并定义功能:

1. Business Perspective (Product Owner/BA)

1. 业务视角(产品负责人/业务分析师)

  • What problem are we solving?
  • What value does it provide?
  • What are the business rules?
  • 我们要解决什么问题?
  • 它能提供什么价值?
  • 有哪些业务规则?

2. Development Perspective (Developer)

2. 开发视角(开发人员)

  • How might we build this?
  • What are the technical constraints?
  • What are the edge cases?
  • 我们该如何构建这个功能?
  • 有哪些技术限制?
  • 存在哪些边缘情况?

3. Testing Perspective (Tester/QA)

3. 测试视角(测试人员/QA)

  • What could go wrong?
  • What are we missing?
  • How will we verify this works?
  • 可能会出现什么问题?
  • 我们遗漏了什么?
  • 我们如何验证功能正常工作?

Example Three Amigos Session

Three Amigos会议示例

Feature: Password Reset
Business: "Users who forget their password need a way to reset it via email."
Developer: "We'll need to generate secure tokens with expiration. How long should tokens be valid?"
Tester: "What happens if they request multiple reset emails? Can old tokens still be used?"
Business: "Tokens should be valid for 1 hour. Multiple requests should invalidate old tokens."
Developer: "Should we rate-limit reset requests to prevent abuse?"
Tester: "What if the email address doesn't exist in our system?"
Business: "For security, show the same success message whether or not the email exists."
Outcome: Concrete examples that become scenarios:
gherkin
Scenario: Request password reset with valid email
  Given a user account exists for "user@example.com"
  When I request a password reset for "user@example.com"
  Then I should receive a reset email
  And the reset link should be valid for 1 hour

Scenario: Request password reset with non-existent email
  When I request a password reset for "nonexistent@example.com"
  Then I should see a success message
  But no email should be sent

Scenario: Multiple password reset requests
  Given I have requested a password reset
  When I request another password reset
  Then the previous reset link should be invalidated
  And I should receive a new reset email
功能:密码重置
业务方:"忘记密码的用户需要通过邮箱重置密码的途径。"
开发人员:"我们需要生成带有效期的安全令牌。令牌的有效期应该设为多久?"
测试人员:"如果用户多次请求重置邮件,会发生什么?旧令牌还能使用吗?"
业务方:"令牌有效期应为1小时。多次请求应使旧令牌失效。"
开发人员:"我们是否应该对重置请求做限流处理以防止滥用?"
测试人员:"如果系统中不存在该邮箱地址怎么办?"
业务方:"为了安全,无论邮箱是否存在,都显示相同的成功提示。"
结果:形成可转化为场景的具体示例:
gherkin
Scenario: Request password reset with valid email
  Given a user account exists for "user@example.com"
  When I request a password reset for "user@example.com"
  Then I should receive a reset email
  And the reset link should be valid for 1 hour

Scenario: Request password reset with non-existent email
  When I request a password reset for "nonexistent@example.com"
  Then I should see a success message
  But no email should be sent

Scenario: Multiple password reset requests
  Given I have requested a password reset
  When I request another password reset
  Then the previous reset link should be invalidated
  And I should receive a new reset email

Living Documentation

活文档

BDD scenarios serve as:
  1. Executable Specifications: Automated tests that verify behavior
  2. Documentation: Up-to-date description of how the system works
  3. Common Language: Shared vocabulary between business and technical teams
  4. Regression Suite: Safety net when making changes
BDD场景可作为:
  1. 可执行的规格说明:验证行为的自动化测试
  2. 文档:系统工作方式的最新描述
  3. 通用语言:业务与技术团队之间的共享词汇
  4. 回归测试套件:修改代码时的安全保障

Example: Living Documentation

示例:活文档

gherkin
Feature: Promotional Discount Application
  To attract customers and increase sales
  As a marketing manager
  I want to offer promotional discounts

  Rule: Percentage discounts apply to order subtotal
    Example: 20% off for orders over $100
      Given I have a $150 order
      When I apply a "20% off" promotion
      Then my discount should be $30
      And my order total should be $120

  Rule: Minimum purchase amount must be met
    Example: Promotion requires $50 minimum
      Given I have a $40 order
      When I try to apply a "$50 minimum" promotion
      Then the promotion should not apply
      And I should see "Minimum purchase not met"

  Rule: Only one promotion per order
    Example: Cannot stack multiple promotions
      Given I have a $100 order
      And I have applied "10% off"
      When I try to apply "Free shipping"
      Then I should see "One promotion per order"
      And only "10% off" should be applied
gherkin
Feature: Promotional Discount Application
  To attract customers and increase sales
  As a marketing manager
  I want to offer promotional discounts

  Rule: Percentage discounts apply to order subtotal
    Example: 20% off for orders over $100
      Given I have a $150 order
      When I apply a "20% off" promotion
      Then my discount should be $30
      And my order total should be $120

  Rule: Minimum purchase amount must be met
    Example: Promotion requires $50 minimum
      Given I have a $40 order
      When I try to apply a "$50 minimum" promotion
      Then the promotion should not apply
      And I should see "Minimum purchase not met"

  Rule: Only one promotion per order
    Example: Cannot stack multiple promotions
      Given I have a $100 order
      And I have applied "10% off"
      When I try to apply "Free shipping"
      Then I should see "One promotion per order"
      And only "10% off" should be applied

Ubiquitous Language

通用语言

Develop and use a shared vocabulary:
Technical Jargon:
"When the user submits the form, we validate the input,
hash the password with bcrypt, insert a record into the
users table, and return a 201 response."
Ubiquitous Language:
"When a customer registers, we verify their information,
create their account, and send a welcome email."
开发并使用共享词汇:
技术行话
"When the user submits the form, we validate the input,
hash the password with bcrypt, insert a record into the
users table, and return a 201 response."
通用语言
"When a customer registers, we verify their information,
create their account, and send a welcome email."

Building Ubiquitous Language

构建通用语言

Discover terms through conversation:
  • What do you call this?
  • What's the difference between X and Y?
  • When does this state change?
Document terms in scenarios:
gherkin
undefined
通过对话发掘术语
  • 你们把这个叫什么?
  • X和Y有什么区别?
  • 这个状态什么时候会改变?
在场景中记录术语
gherkin
undefined

Use "Member" not "User" (business term)

Use "Member" not "User" (business term)

Given I am a Gold Member
Given I am a Gold Member

Use "Place order" not "Submit order" (domain term)

Use "Place order" not "Submit order" (domain term)

When I place an order
When I place an order

Use "Pending" not "In progress" (system state)

Use "Pending" not "In progress" (system state)

Then the order should be Pending

**Keep a glossary:**
Member: A customer with a subscription Guest: A customer without a subscription Order: A collection of items ready for purchase Cart: A temporary collection of items being considered
undefined
Then the order should be Pending

**维护术语表**:
Member: A customer with a subscription Guest: A customer without a subscription Order: A collection of items ready for purchase Cart: A temporary collection of items being considered
undefined

Example Mapping

示例映射

A workshop technique to explore features with examples:
一种通过示例探索功能的工作坊技术:

The Four Colors

四种颜色卡片

Yellow Cards: User Stories/Features Blue Cards: Rules (acceptance criteria) Green Cards: Examples (scenarios) Red Cards: Questions (uncertainties)
黄色卡片:用户故事/功能 蓝色卡片:规则(验收标准) 绿色卡片:示例(场景) 红色卡片:疑问(不确定点)

Example Mapping Session

示例映射工作坊示例

Story: User registration
Rules (Blue):
  • Email must be unique
  • Password must be strong
  • Age must be 18+
Examples (Green):
  • Register with valid details → Success
  • Register with existing email → Error
  • Register with weak password → Error
  • Register under 18 → Error
Questions (Red):
  • Do we verify email addresses?
  • What defines a "strong" password?
  • Do we need parent consent for minors?
用户故事:用户注册
规则(蓝色):
  • 邮箱必须唯一
  • 密码必须强度足够
  • 年龄必须满18岁
示例(绿色):
  • 使用有效信息注册 → 成功
  • 使用已存在的邮箱注册 → 错误
  • 使用弱密码注册 → 错误
  • 未满18岁注册 → 错误
疑问(红色):
  • 我们需要验证邮箱地址吗?
  • 什么是"强密码"的定义?
  • 未成年人需要家长同意吗?

Specification by Example

实例化需求

Use concrete examples to drive development:
使用具体示例驱动开发:

Vague Requirement

模糊需求

"Users should be able to search for products."
"用户应该能够搜索商品。"

Specification by Example

实例化需求

gherkin
Scenario: Search by product name
  Given products "Laptop", "Mouse", "Keyboard" exist
  When I search for "lap"
  Then I should see "Laptop" in results
  But I should not see "Mouse" or "Keyboard"

Scenario: Search with no results
  Given products "Laptop", "Mouse" exist
  When I search for "phone"
  Then I should see "No results found"

Scenario: Search is case-insensitive
  Given a product "Laptop" exists
  When I search for "LAPTOP"
  Then I should see "Laptop" in results
gherkin
Scenario: Search by product name
  Given products "Laptop", "Mouse", "Keyboard" exist
  When I search for "lap"
  Then I should see "Laptop" in results
  But I should not see "Mouse" or "Keyboard"

Scenario: Search with no results
  Given products "Laptop", "Mouse" exist
  When I search for "phone"
  Then I should see "No results found"

Scenario: Search is case-insensitive
  Given a product "Laptop" exists
  When I search for "LAPTOP"
  Then I should see "Laptop" in results

Outside-In Development

由外而内的开发

Start from the outside (user-facing behavior) and work inward:
  1. Write a failing scenario (acceptance test)
  2. Write a failing unit test (for the layer you're working on)
  3. Write minimum code to make unit test pass
  4. Refactor
  5. Repeat until scenario passes
Scenario (Acceptance) ─┐
                       ├─> Controller Test ─┐
                       │                    ├─> Service Test ─┐
                       │                    │                 ├─> Code
                       │                    │                 │
                       │                    ├─ Service        │
                       │                    │                 │
                       ├─ Controller        │                 │
                       │                    │                 │
Scenario Passes ───────┴────────────────────┴─────────────────┘
从外部(用户可见的行为)开始,向内推进:
  1. 编写失败的场景(验收测试)
  2. 编写失败的单元测试(针对当前工作的层级)
  3. 编写最少代码使单元测试通过
  4. 重构
  5. 重复直到场景通过
Scenario (Acceptance) ─┐
                       ├─> Controller Test ─┐
                       │                    ├─> Service Test ─┐
                       │                    │                 ├─> Code
                       │                    │                 │
                       │                    ├─ Service        │
                       │                    │                 │
                       ├─ Controller        │                 │
                       │                    │                 │
Scenario Passes ───────┴────────────────────┴─────────────────┘

BDD vs TDD

BDD vs TDD

TDD (Test-Driven Development):
  • Developer-focused
  • Tests implementation
  • Red-Green-Refactor cycle
  • Unit tests guide design
BDD (Behavior-Driven Development):
  • Business-focused
  • Tests behavior
  • Conversation-Specification-Automation
  • Scenarios guide development
They complement each other:
  • BDD: What should we build? (outside-in)
  • TDD: How should we build it? (inside-out)
TDD(测试驱动开发):
  • 以开发人员为中心
  • 测试实现细节
  • 红-绿-重构循环
  • 单元测试指导设计
BDD(行为驱动开发):
  • 以业务为中心
  • 测试行为
  • 对话-规格说明-自动化流程
  • 场景指导开发
二者相辅相成
  • BDD:我们应该构建什么?(由外而内)
  • TDD:我们应该如何构建?(由内而外)

Key Principles

关键原则

  1. Collaboration is essential - BDD requires active participation from business, development, and testing
  2. Examples clarify requirements - Concrete examples reveal ambiguities and edge cases
  3. Automate what matters - Not everything needs to be automated, focus on high-value scenarios
  4. Think behaviors, not tests - Describe what the system does, not how it's tested
  5. Iterate and refine - Scenarios evolve as understanding deepens
  6. Keep scenarios maintainable - Write clear, focused scenarios that are easy to update
  1. 协作至关重要 - BDD需要业务、开发和测试团队的积极参与
  2. 示例明确需求 - 具体示例揭示模糊点和边缘情况
  3. 自动化重要内容 - 并非所有内容都需要自动化,聚焦高价值场景
  4. 思考行为而非测试 - 描述系统做什么,而非如何测试
  5. 迭代与优化 - 场景随理解加深而演进
  6. 保持场景可维护 - 编写清晰、聚焦的场景,便于更新

Common Misconceptions

常见误解

❌ "BDD is just testing with Cucumber" ✅ BDD is a collaborative practice; tools are just enablers
❌ "BDD means writing tests before code" ✅ BDD means discovering requirements through examples before implementation
❌ "BDD scenarios should test everything" ✅ BDD scenarios should document key behaviors; use unit tests for details
❌ "Only testers write scenarios" ✅ Business, developers, and testers collaborate on scenarios
❌ "BDD slows down development" ✅ BDD reduces rework by building the right thing the first time
❌ "BDD is just testing with Cucumber" ✅ BDD是一种协作实践;工具只是实现手段
❌ "BDD means writing tests before code" ✅ BDD意味着在实现前通过示例发掘需求
❌ "BDD scenarios should test everything" ✅ BDD场景应记录关键行为;细节用单元测试覆盖
❌ "Only testers write scenarios" ✅ 业务、开发和测试人员协作编写场景
❌ "BDD slows down development" ✅ BDD通过从一开始就构建正确的功能减少返工

Benefits of BDD

BDD的优势

  • Reduced rework: Build the right thing from the start
  • Better collaboration: Shared understanding across roles
  • Living documentation: Always up-to-date specifications
  • Faster onboarding: New team members learn from scenarios
  • Regression safety: Automated scenarios catch breaking changes
  • Business confidence: Stakeholders see value being delivered
Remember: BDD is fundamentally about communication and collaboration. The goal is to build software that delivers real value by ensuring everyone has a shared understanding of what needs to be built.
  • 减少返工:从一开始就构建正确的功能
  • 提升协作:跨角色达成共识
  • 活文档:始终最新的规格说明
  • 加速新成员融入:新团队成员通过场景了解系统
  • 回归安全保障:自动化场景捕获破坏性变更
  • 增强业务信心:利益相关者能看到价值交付
记住:BDD本质上是关于沟通与协作的实践。其目标是通过确保所有人对需要构建的内容达成共识,交付真正有价值的软件。