撰写 QA 真正能测试的边界情况

撰写 QA 真正能测试的边界情况
Daniel Marsh · Spec-First 工程笔记

"合理处理边界情况。"我几乎每周都能在 spec 里看到这句话。它什么都没说。QA 没法测试"合理"——他们需要具体的输入、具体的触发条件、具体的预期结果。下面是我写边界情况的方式,让 QA 不用追问一句就能把它们变成测试用例。

发布于 2026-03-01 · ✓ 已更新 2026-05-11 · 阅读约 7 分钟 · 作者:Spec Coding 编辑团队 · 审校:编辑政策

内容整理说明

复查日期:2026-05-06。本文已重新纳入公开索引路径,作为 验收标准 Hub 的延伸阅读。我们补齐了专题路径、站内链接和可索引元数据,便于搜索引擎和读者理解它与核心主题的关系。

"可测试"的判定标准

一条边界情况是可测试的,前提是三件事都具体:输入、触发条件、以及可观察到的预期结果。如果其中任何一项是没有宾语的动词、或是拿形容词充当数字,那它就还不是测试用例——只是一厢情愿。

快速检查的方法是:QA 工程师不打开 Slack 就能写出这个测试吗?如果答案是"不能",那 spec 就还没写完。

我每次审 spec 都会对照的五个类别

绝大多数被漏掉的边界情况都落在这五个桶里。我审 spec 的时候会把这份清单开着,QA 写测试计划时也开着。

1. 输入边界

每个输入字段至少有六个值得关注的取值:空值、一个、允许的最大值、最大值加一、负数、以及 unicode 或特殊字符。不是每个字段都六个都适用,但默认假设应该是"六个都可能要命",除非你能证明不会。

- Given the display name field (max 50 chars)
  When the user submits "" (empty)
  Then the form shows "Name is required" inline; submit is disabled

- Given the display name field
  When the user submits 51 characters
  Then the request is rejected with 422 and "Name too long (max 50)"

- Given the display name field
  When the user submits 50 characters including emoji (4-byte unicode)
  Then the request succeeds and the name renders correctly in the user list

2. 状态转换

任何带有 status 字段的东西都有可能走错的转换路径。大多数 spec 描述的是快乐路径("user → active → cancelled"),却跳过那些乱糟糟的路径:重新激活、重复取消、在挂起变更期间取消。生产事故就住在这些地方。

对于每一个状态转换,都要写清楚:在错误状态下尝试这个转换时应该发生什么。"用户尝试取消一个已取消的账户"是真实存在的场景,而且在上线第一天就会发生。

3. 并发与竞态条件

只要两个用户可以操作同一条记录,你就已经有了并发问题——无论 spec 承不承认。真正要测的不是快乐路径能不能跑通,而是两个用户在 100ms 内都点了提交时会发生什么。

把这些写下来。QA 没法测试"后写覆盖并显示冲突横幅",除非 spec 明确规定这就是规则。

4. 时间相关的边界

跟时间相关的边界往往咬得最狠,因为它们在时钟跨过那个点之前是看不见的。常见的几种:

5. 错误路径

每一条快乐路径 AC 至少对应三条错误路径:校验失败、授权失败、下游依赖失败。spec 应当说明用户在每一种情况下看到什么。

- Given the user is authenticated but lacks "admin" role
  When they request /admin/users
  Then the response is 403 with body {"error": "forbidden", "required_role": "admin"}
  And the UI shows "You don't have access to this page" with a link back

- Given the downstream billing service returns 503
  When the user submits checkout
  Then the UI shows "Payment is temporarily unavailable — please retry in a minute"
  And the request is retried up to 3× with exponential backoff server-side
  And no order record is created until at least one retry succeeds

如何在 spec 里组织这些内容

我会把边界情况放在快乐路径 AC 下面的一个专门小节里,按上面五类分组。每一条边界情况都有一个 Given/When/Then 块,格式跟快乐路径一致。

我强制执行两条结构规则:

QA 可以把 spec 打回去的几种情况

如果我站在 QA 这边做评审,看到下面这些情况我会把 spec 退回去让作者改:

五分钟测试

发 spec 之前跑一遍这个检查:挑一条边界情况,假装你是 QA 在写测试。你能在不打开代码、不问人的前提下,写出确切的输入、确切的触发、确切的断言吗?可以的话,这条就过了。不行的话,spec 还欠你一句话。

把这个检查扩展到整个边界情况小节,你就能在它们三周后出现在 QA 站会之前,提前抓住大约 80% 的歧义。

评审时看什么

这篇文章适合用在把边界条件交给 QA时。别从“原则”聊起,直接拿一条真实改动来对照,看看规格里还缺什么。

QA 不缺“多考虑边界”的提醒。QA 缺的是可以直接执行的例子。

例子:“网络失败”不是可测试边界。要写成“用户点击支付后,支付 API 超时 30 秒;订单保持 pending,禁止重复支付,并显示重试按钮”。QA 才知道怎么复现,也知道怎样算通过。

落地例子

文件上传的边界条件可以写成一个场景:用户在慢网络下上传 200 MB 文件,进度到 80% 时断网,随后刷新浏览器。预期结果可以是断点续传、明确失败并允许重试,或者明确丢失进度。哪一种都可以测试,关键是不能只写“处理中断上传”。

边界条件越像真实场景,QA 越少猜测。规格也能暴露产品选择:我们是在保护用户时间,还是接受重新上传的成本。

边界条件要带输入,不要只写名词

QA 不能测试“处理异常情况”。他们能测试的是一个具体输入、起始状态、操作和预期输出。写边界条件时,我会强迫每条都包含这四个部分。

Testable edge case:
- Start state: user has one unpaid invoice and card is expired
- Input: retry payment with same invoice_id within 60 seconds
- Action: user clicks Pay Now twice
- Expected: one provider charge attempt, second request returns existing attempt_id
- Evidence: ledger has one pending payment row and UI shows one banner

边界:不要把低概率但低影响的情况全塞进首版。优先写会导致钱错、权限错、数据丢失和用户无法恢复的边界。

给边界条件标优先级

QA 时间有限,边界条件要分 release-blocking、should-test 和 exploratory。涉及钱、权限、数据删除、重复提交和不可恢复状态的边界优先级最高。排序写进 spec,测试取舍才不会靠临场感觉。

边界条件写完后,再补一列证据:API response、数据库状态、事件、日志、UI 文案或截图。QA 不该靠读代码判断通过。每条边界都能连到证据,才算从“想到了”变成“测得到”。

我还会让每个边界条件带一个 fixture 名称,例如 expired-invite.json、duplicate-refund.json、permission-revoked.json。fixture 进入测试仓库后,API、UI、日志和数据库断言都能复用同一份输入,边界就不再只是文档里的句子。

前后对比:把“边界情况”改成 QA 可测夹具

“网络失败要处理好”和“QA 可以直接测”的差别,在于是否给了夹具。第二种写法可以直接放进测试用例,不需要再开会问产品。

修改前:
- 网络失败时要优雅处理。

修改后:
- Given 已登录买家的购物车里有一个 49 美元商品
  And 支付服务已经扣款,但应用收到 30 秒 timeout
  When 买家在 2 分钟内再次点击 Pay
  Then 应用复用原来的 idempotency key
   And 页面显示“支付处理中”,不会再次扣款
   And 客服能通过 order_id 在审计日志里查到 pending payment。

这段不长,但它交代了数据、触发、时间窗口、断言和客服排查信号,联调和验收都更容易落地。

关键词:edge cases · acceptance criteria · QA testing · spec writing · testable specifications

专题阅读路径

先读主题 Hub,再用下面的相邻文章和模板把这篇内容放进完整工作流。

交互式生成规格
填写表单,生成完整的功能规格 Markdown——免费使用,无需注册。
试用规格生成器

编辑说明

本文面向软件交付团队,介绍如何撰写 QA 真正能测试的边界情况。示例均为工程场景说明,不构成法律、税务或投资建议。