BDD案例

wen java案例 3

本文目录导读:

BDD案例

  1. 案例一:电商系统 - 优惠券叠加规则
  2. 案例二:银行系统 - ATM取款
  3. 案例三:技术实现 - 登录功能(含Mock)
  4. 如何撰写有效的BDD案例?(核心要点总结)
  5. BDD工具链推荐

BDD(行为驱动开发)案例通常围绕一个具体的用户故事展开,通过“Given-When-Then”结构描述预期行为。

这里提供3个不同风格的案例,从业务需求代码实现的完整闭环,供你参考。


电商系统 - 优惠券叠加规则

【背景】

产品经理新出一个规则:“满减券”和“折扣券”不能叠加使用,系统自动选择优惠力度最大的方案

用户故事 (User Story)

作为 一位网购用户 我希望 在结算时系统能自动选择最优优惠 以便于 我用最少的钱买到心仪的商品

验收标准 (BDD Scenario - Gherkin 语言)

这是BDD最核心的部分,通常写在 .feature 文件中:

# file: checkout_discount.feature
Feature: 结算页优惠计算
  作为购物者
  我希望系统自动计算最优优惠
  以便于支付最少的金额
  Scenario: 满减券优于折扣券时,自动使用满减券
    Given 我的购物车中有价值 "500" 元的商品
    And 我有一张 "满400减50" 的满减券
    And 我有一张 "9折" 的折扣券
    When 我点击结算按钮
    Then 系统应该展示应付金额为 "450" 元
    And 系统应展示优惠说明为 "已使用满减券"
  Scenario: 折扣券优于满减券时,自动使用折扣券
    Given 我的购物车中有价值 "200" 元的商品
    And 我有一张 "满199减20" 的满减券
    And 我有一张 "8折" 且最高抵扣50元的折扣券
    When 我点击结算按钮
    Then 系统应该展示应付金额为 "160" 元
    And 系统应展示优惠说明为 "已使用折扣券"
  Scenario: 优惠券均不满足条件时,原价支付
    Given 我的购物车中有价值 "100" 元的商品
    And 我有一张 "满200减10" 的满减券
    And 我有一张 "9.5折" 的折扣券
    When 我点击结算按钮
    Then 系统应该展示应付金额为 "100" 元
    And 系统应提示 "暂无可用的优惠券"

自动化测试实现 (以 Python Behave 为例)

BDD的关键在于“活文档”——上面的Gherkin文本直接驱动代码运行。

# file: steps/test_checkout_steps.py
from behave import given, when, then
# 上下文存储数据
@given('我的购物车中有价值 "{price}" 元的商品')
def step_cart_price(context, price):
    context.cart_price = float(price)
@given('我有一张 "{rule}" 的满减券')
def step_full_reduction(context, rule):
    # 解析规则 "满400减50"
    parts = rule.split('减')
    threshold = float(parts[0].replace('满', ''))
    discount = float(parts[1])
    context.full_reduction = {'threshold': threshold, 'discount': discount}
@given('我有一张 "{discount}" 的折扣券')
def step_discount_coupon(context, discount):
    # 只做简单存储,实际会解析折扣率
    context.discount_coupon = float(discount.replace('折', '')) / 10
@when('我点击结算按钮')
def step_click_checkout(context):
    # 核心业务算法:模拟真实逻辑
    best_price = context.cart_price
    best_message = "暂无可用的优惠券"
    # 方案1:满减计算
    if hasattr(context, 'full_reduction'):
        fr = context.full_reduction
        if context.cart_price >= fr['threshold']:
            candidate = context.cart_price - fr['discount']
            if candidate < best_price:
                best_price = candidate
                best_message = "已使用满减券"
    # 方案2:折扣计算(注意该案例中折扣没有封顶,为了简化)
    if hasattr(context, 'discount_coupon'):
        candidate = context.cart_price * context.discount_coupon
        if candidate < best_price:
            best_price = candidate
            best_message = "已使用折扣券"
    context.final_price = best_price
    context.final_message = best_message
@then('系统应该展示应付金额为 "{expected}" 元')
def step_check_price(context, expected):
    assert context.final_price == float(expected), f"预期{expected},实际{context.final_price}"
@then('系统应展示优惠说明为 "{expected_msg}"')
def step_check_msg(context, expected_msg):
    assert context.final_message == expected_msg, f"预期{expected_msg},实际{context.final_message}"
@then('系统应提示 "{expected_msg}"')
def step_check_prompt(context, expected_msg):
    assert context.final_message == expected_msg, f"预期提示{expected_msg},实际{context.final_message}"

银行系统 - ATM取款

【业务规则】 用户余额不足时,ATM机拒绝出钞,并先退卡。

BDD 场景描述:

Feature: ATM取款
  Scenario: 账户余额不足,取款失败
    Given 我的储蓄卡余额为 100 元
    And 我的银行卡密码是正确的
    When 我在ATM机上取款 200 元
    Then ATM机应该提示 "余额不足"
    And 系统应该发出退卡指令

技术实现 - 登录功能(含Mock)

【业务规则】 用户输入验证码错误超过5次,账号锁定30分钟。

Feature: 用户登录安全策略
  Scenario Outline: 连续输错验证码导致账号锁定
    Given 用户 "<username>" 存在且状态为启用
    When 用户连续输入错误验证码 "<times>" 次
    Then 该账号状态应变为 "锁定"
    And 系统应记录锁定时间为 "30" 分钟
    Examples:
      | username | times |
      | test01   | 5     |
      | test02   | 6     |

如何撰写有效的BDD案例?(核心要点总结)

  1. 使用业务语言,而非技术语言

    • ✅ 错误写法:Given 用户点击了名称为"Submit"的按钮 (Button ID=101)
    • ❌ 正确写法:Given 用户提交了有效的登录表单
  2. 关注行为,而非实现细节

    BDD不关心数据库怎么存的,只关心界面上显示什么、接口返回什么结果。

  3. “Given-When-Then”是铁三角

    • Given (上下文):描述初始状态,如“用户已登录”、“卡内余额有100元”。
    • When (触发动作):用户做了什么操作,如“点击结算”、“取款200元”。
    • Then (预期结果):系统如何响应,如“页面显示成功”、“数据库写入记录”。
  4. 避免“And”使用过度

    • 如果一个场景里有超过5个And,说明场景可能过于复杂,建议拆分成多个小场景。

BDD工具链推荐

  • Cucumber (Ruby/Java/Javascript)
  • Behave (Python)
  • SpecFlow (.NET)
  • JBehave (Java)

BDD的价值在于: 它是一份可执行的规格说明书,产品经理、开发、测试、业务人员都看同一份Gherkin文档,减少沟通误解,当代码逻辑改变时,自动化测试会失败,从而提醒团队“业务规则被破坏了”。

上一篇Cucumber案例

下一篇ATDD案例

抱歉,评论功能暂时关闭!