验收标准怎么写
没有验收标准的需求,等于没有需求
需求文档写了几页,功能列表列了二十条,用户故事写了十条——但如果你问「怎么算做完了」,对方支支吾吾说「能用就行」「看着差不多就行」,那这份需求和没写没什么区别。
验收标准(Acceptance Criteria,简称 AC)是需求文档中最容易被忽略、也最容易写烂的部分。很多人把它当成一种形式,随便写几句「功能正常、体验流畅」就交差了。结果开发做出来一个版本,测试发现不知道怎么验证,产品觉得不对又说不清哪里不对,最后反复返工。
在 AI 编程场景下,这个问题更严重。AI 不会问你「你觉得这样行不行」,它只会严格按照你的指令执行。如果你的验收标准是模糊的,AI 的输出也是模糊的——它可能做出了一个「技术上能跑」但「业务上完全不对」的东西,而你还得花大量时间告诉 AI 哪里需要改。
本文会系统讲清楚:验收标准到底是什么、Given-When-Then 格式怎么用、验收标准有哪些层次、如何写出可测试的验收标准,以及在 AI 编程中如何让验收标准充当测试用例。
验收标准的定义和重要性
什么是验收标准
验收标准是一组预定义的条件,只有当这些条件全部满足时,一个用户故事或功能才能被标记为「完成」。
换句话说,验收标准回答的是一个很简单的问题:「做完之后,我怎么验证它确实做对了?」
| 维度 | 验收标准的角色 |
|---|---|
| 对产品 | 需求的可验证表达,明确「做成什么样」 |
| 对开发 | 实现的边界和约束,告诉开发者「到什么程度算完」 |
| 对测试 | 测试用例的直接来源,每一条 AC 对应一组测试 |
| 对 AI | 精确的指令约束,AI 输出的评判标准 |
为什么验收标准这么重要
验收标准的重要性可以从反面来看——没有验收标准时,会发生什么:
- 需求没有终点:开发不知道做到什么程度算完,产品觉得做出来了但「不太对」,双方扯不清楚
- 测试没有依据:测试人员只能凭经验去测,核心场景可能漏掉,边缘情况更是没人管
- 沟通成本翻倍:每个人对「做完了」的理解不同,验收变成了主观判断
- AI 编程场景失控:没有明确的验收标准,AI 输出质量不稳定,你只能靠反复 prompt 去逼近想要的结果
验收标准的本质是一种「契约」——它把模糊的期望变成可验证的条件。有了这份契约,团队里的每个人(包括 AI)都知道「做到什么程度,才算完成」。
Given-When-Then 格式详解
两种主流的验收标准格式
在敏捷开发中,验收标准主要有两种写法:
- 规则格式(Rule-based):用清单列表的方式描述系统应该满足的规则
- 场景格式(Scenario-based):用 Given-When-Then 结构描述具体场景
规则格式适合简单的、列表式的约束。但当你需要描述「在什么条件下、做什么操作、期望什么结果」这种有明确场景的需求时,Given-When-Then 格式更清晰、更容易转化为测试用例。
Given-When-Then 的三段结构
Given-When-Then 源自行为驱动开发(Behavior Driven Development,BDD),是一种结构化的验收标准编写方式。它的三个部分分别描述:
| 关键字 | 含义 | 作用 |
|---|---|---|
| Given(假定) | 描述前置条件和初始状态 | 设定场景的起点,明确系统处于什么状态 |
| When(当) | 描述用户执行的操作 | 明确触发行为,用户做了什么 |
| Then(然后) | 描述期望的系统响应 | 定义可验证的结果,系统应该返回什么 |
此外还有一个可选的 And(而且),用来在任意一段之后追加补充条件或结果。
GWT 格式模板
下面是 Given-When-Then 格式在不同场景下的模板:
| 场景类型 | Given | When | Then |
|---|---|---|---|
| 用户登录 | 用户在登录页面,已输入正确的邮箱 | 用户点击「登录」按钮 | 系统跳转到首页,显示用户头像和昵称 |
| 表单验证 | 用户在注册页面,密码输入框为空 | 用户点击「提交注册」 | 系统显示错误提示「请输入密码」,表单不提交 |
| 数据查询 | 用户已登录,且订单列表中有 3 条记录 | 用户点击「查看订单」 | 系统展示 3 条订单记录,按时间倒序排列 |
| 支付流程 | 用户购物车有 2 件商品,总价 200 元 | 用户确认支付并输入正确密码 | 系统扣款成功,订单状态变为「已支付」,跳转成功页面 |
一个完整的 GWT 示例
以「用户重置密码」功能为例:
场景:用户通过邮箱重置密码
Given 用户已注册账户,邮箱为 [email protected]
And 用户当前未登录
When 用户在登录页面点击「忘记密码」
And 输入邮箱 [email protected] 并提交
Then 系统发送一封包含重置链接的邮件到 [email protected]
And 页面显示「重置邮件已发送,请查收」
And 重置链接有效期为 30 分钟
场景:用户使用重置链接设置新密码
Given 用户已收到重置密码邮件
And 重置链接在有效期内
When 用户点击重置链接
And 输入新密码「NewPass123!」并确认
Then 系统更新密码为「NewPass123!」
And 旧密码失效
And 页面跳转到登录页,显示「密码重置成功,请重新登录」
注意上面的示例中,一个功能拆出了两个独立场景——一个是「发起重置」,一个是「完成重置」。这是一个重要原则:每条验收标准只覆盖一个场景,不要把多个场景揉在一起。
验收标准的层次
验收标准不是只写在一个层级的。一个完整的产品需求,验收标准应该分布在三个层次上,从宏观到微观逐步细化:
| 层次 | 关注点 | 编写时机 | 谁来验证 |
|---|---|---|---|
| 系统级 | 整个产品的业务目标和非功能需求 | PRD 编写阶段 | 产品负责人、利益相关者 |
| 页面级 | 单个页面或模块的交互和展示 | 需求细化阶段 | 产品经理、设计师、前端开发 |
| 功能级 | 单个功能点的具体行为 | 用户故事拆分后 | 开发、测试 |
系统级验收标准
系统级验收标准关注的是产品作为一个整体验收时需要满足的条件。它通常包括性能指标、兼容性要求、安全要求等非功能性需求。
示例:
系统级验收标准——AI 翻译工具
- 系统支持的最大文件大小为 50KB
- 翻译响应时间不超过 30 秒
- 系统同时支持的最大并发请求数为 10
- 所有用户数据通过 HTTPS 传输
- 系统兼容 Chrome、Firefox、Safari 最新两个主版本
页面级验收标准
页面级验收标准关注的是单个页面的展示和交互行为。它把页面的每个关键元素和交互都定义清楚。
示例:
页面级验收标准——翻译结果页面
- 原文区域显示用户上传的 Markdown 内容
- 翻译结果区域显示 AI 生成的中文翻译
- 原文和翻译结果左右分栏展示
- 代码块在翻译结果中原样保留,不做翻译
- 每个段落旁边有「编辑」按钮,点击后变为可编辑状态
- 编辑后自动保存,页面右上角显示「已保存」状态
功能级验收标准
功能级验收标准是最细的颗粒度,通常用 Given-When-Then 格式编写,直接对应测试用例。
示例:
功能级验收标准——上传 Markdown 文件
Given 用户在翻译页面
And 用户选择一个 .md 文件
When 用户点击「上传并翻译」按钮
Then 系统校验文件类型为 .md
And 系统校验文件大小不超过 50KB
And 系统调用翻译 API 进行翻译
And 翻译完成后跳转到翻译结果页面
三个层次的关系
三个层次是自上而下的关系:系统级定义大方向,页面级定义每个页面的预期表现,功能级定义每个操作的具体行为。写验收标准时,先从系统级开始确定整体约束,再细化到页面和功能级。
如何写可测试的验收标准
「可测试」是验收标准最重要的属性。如果一条验收标准无法被测试,那它就不是验收标准,只是一句美好的愿望。
好验收标准 vs 差验收标准
| 维度 | 差的验收标准 | 好的验收标准 |
|---|---|---|
| 可测量性 | 「页面加载要快」 | 「页面首屏加载时间不超过 2 秒」 |
| 具体性 | 「支持多种文件格式」 | 「支持 .md 和 .txt 两种格式」 |
| 无歧义性 | 「界面要好看」 | 「主色调使用 #1a1a1a,正文字号 16px」 |
| 独立性 | 「用户能完成整个翻译流程」 | 「用户能上传一个 .md 文件」+「用户能查看翻译结果」 |
| 可验证性 | 「系统要稳定」 | 「系统连续运行 7 天无崩溃」 |
| 正向表述 | 「不要有 bug」 | 「所有表单校验错误在提交后 1 秒内显示提示」 |
写可测试验收标准的五条原则
原则一:用具体数字替代模糊形容词
「快速」→「2 秒内」,「大量」→「1000 条以内」,「长时间」→「持续 24 小时」。凡是无法量化的描述,都不是验收标准。
原则二:一条标准只验证一件事
「用户可以登录并查看订单」应该拆成两条:「用户可以登录」和「登录后可以查看订单列表」。一条标准验证两件事,当测试失败时,你不知道是哪个环节出了问题。
原则三:明确前置条件
每条验收标准都应该说清楚「在什么状态下」开始验证。「用户已登录」「购物车有 3 件商品」「账户余额为 100 元」——这些前置条件写清楚了,测试才能复现。
原则四:包含正常路径和异常路径
不要只写「用户操作正确时系统怎么响应」,也要写「用户操作错误时系统怎么处理」。空值、超长输入、网络异常、权限不足——这些异常路径的验收标准同样重要。
原则五:用主动语态,避免被动语态
「邮件被发送给用户」→「系统向用户发送邮件」。主动语态明确了「谁做了什么」,避免歧义。
异常路径验收标准示例
场景:上传超过大小限制的文件
Given 用户在翻译页面
And 文件大小限制为 50KB
When 用户选择一个 80KB 的 .md 文件
And 点击「上传并翻译」按钮
Then 系统不发起翻译请求
And 页面显示错误提示「文件大小超过限制(最大 50KB)」
And 文件不被上传到服务器
场景:翻译 API 调用失败
Given 用户已成功上传文件
And 翻译 API 当前不可用
When 系统调用翻译 API
Then 系统在 5 秒内放弃请求
And 页面显示错误提示「翻译服务暂时不可用,请稍后重试」
And 用户上传的文件保留,不丢失
AI 编程中验收标准的特殊作用
在传统团队开发中,验收标准主要服务于测试人员。但在 AI 编程场景下,验收标准的角色发生了变化——它同时承担了三个职责:
- 给 AI 的约束指令:告诉 AI「输出要满足什么条件」
- 给人类的验证清单:让你能快速判断 AI 的输出是否合格
- 给测试的自动化用例:每条 AC 可以直接转化为自动化测试
AI 编程中验收标准的独特要求
| 维度 | 传统团队中的 AC | AI 编程中的 AC |
|---|---|---|
| 精确度 | 开发者可以主动提问和推断 | AI 不会推断,必须完全精确 |
| 格式 | 自然语言即可 | 结构化、可解析的格式效果更好 |
| 异常处理 | 开发者凭经验补充 | 必须显式写出每种异常的处理方式 |
| 边界约束 | 口头约定即可 | 需要明确写出「不做什么」,否则 AI 会扩展范围 |
| 验证方式 | 人工验证 | 尽量写成可自动化验证的形式 |
把验收标准写成 AI 可以直接消费的格式
在 AI 编程中,验收标准不只是写给人看的文档,它同时也是写给 AI 的指令。因此格式上要尽量结构化,方便拆成 prompt:
## 功能:上传 Markdown 文件并翻译
### 验收标准
- [ ] AC1: 上传 .md 文件(≤50KB)→ 调用翻译 API → 30 秒内返回翻译结果
- [ ] AC2: 上传非 .md 文件 → 拒绝上传,提示「仅支持 Markdown 文件」
- [ ] AC3: 上传 >50KB 文件 → 拒绝上传,提示「文件大小超过限制」
- [ ] AC4: 翻译 API 超时 → 显示「翻译服务暂时不可用」,不丢失已上传文件
- [ ] AC5: 翻译结果中代码块内容 = 原文代码块内容(逐字符一致)
- [ ] AC6: 翻译结果页面显示原文(左栏)和译文(右栏)
- [ ] AC7: 点击译文中某段的「编辑」按钮 → 该段变为可编辑
- [ ] AC8: 编辑后失去焦点 → 自动保存,右上角显示「已保存」这种 checkbox 格式的验收标准有两个好处:一是 AI 可以逐条检查自己的输出是否满足;二是你在验收时可以直接勾选,形成验收记录。
案例:用验收标准驱动 AI 完成翻译功能
假设你要让 AI 实现「上传 Markdown 文件并翻译」功能。
没有验收标准的 prompt:
帮我做一个功能,用户可以上传 Markdown 文件,系统自动翻译成中文。
AI 会输出一个「看起来能用」的实现,但你不知道它有没有处理文件大小限制、有没有保留代码块、API 超时怎么办——全要靠你事后验证。
有验收标准的 prompt:
实现上传 Markdown 文件并翻译的功能,必须满足以下验收标准:
AC1: 上传 .md 文件(≤50KB)→ 30 秒内返回翻译结果 AC2: 上传非 .md 文件 → 拒绝上传,提示「仅支持 Markdown 文件」 AC3: 翻译结果中代码块内容 = 原文代码块内容 AC4: 翻译 API 超时 → 显示「翻译服务暂时不可用」 AC5: 不添加任何额外功能(不做文件历史记录,不做批量上传)
第二种 prompt 下,AI 的输出质量和准确度会高很多,因为验收标准帮 AI 划定了精确的边界。
写验收标准的流程
写验收标准不是等到需求写完再补的,它应该和需求定义同步进行。下面的流程图展示了写验收标准的完整过程:
这个流程的关键节点有三个:
- 识别核心场景(步骤 B):先想清楚这个功能最关键的使用场景是什么,不要一上来就写细节
- 补充异常路径(步骤 G-H):正常路径容易写,但异常路径才是验收标准质量的试金石
- 检查可测试性(步骤 I-K):逐条检查,凡是不能测量、不能验证的描述,都要改写成可测试的形式
案例研究
案例一:电商网站的购物车功能
以下是一个电商网站购物车功能的验收标准示例,展示了从用户故事到具体 AC 的完整过程。
用户故事: 作为购物用户,我希望把商品加入购物车,以便稍后统一结算。
系统级验收标准:
- 购物车数据在用户登录状态下持久化保存
- 购物车支持最多 50 件不同商品
- 购物车页面加载时间不超过 2 秒
页面级验收标准:
- 商品详情页有「加入购物车」按钮
- 购物车页面显示商品图片、名称、单价、数量和小计
- 购物车页面底部显示总价
- 数量调整区域有「+」和「-」按钮
- 每个商品行有「删除」按钮
功能级验收标准(GWT 格式):
场景:添加商品到购物车
Given 用户在商品详情页
And 商品库存数量 > 0
And 当前购物车中没有该商品
When 用户点击「加入购物车」按钮
Then 商品被添加到购物车
And 购物车图标上的数量 +1
And 页面显示提示「已加入购物车」
场景:购物车中已有该商品时再次添加
Given 用户在商品详情页
And 购物车中已有该商品,数量为 2
When 用户点击「加入购物车」按钮
Then 购物车中该商品数量变为 3
And 购物车图标更新为新的总数量
场景:商品库存不足时加入购物车
Given 用户在商品详情页
And 商品库存数量为 1
And 购物车中已有该商品,数量为 1
When 用户点击「加入购物车」按钮
Then 系统不增加购物车中该商品的数量
And 页面显示提示「库存不足,无法添加更多」
场景:删除购物车中的商品
Given 用户在购物车页面
And 购物车中有 3 件商品
When 用户点击某件商品的「删除」按钮
Then 该商品从购物车中移除
And 购物车总价重新计算
And 购物车图标数量 -1
这个案例展示了三个层次验收标准的协作:系统级定义了整体约束(性能、容量),页面级定义了展示要求,功能级定义了每种操作的具体行为。三层合在一起,才是完整的验收标准。
案例二:用验收标准驱动 AI 生成登录功能
以下是一个用验收标准驱动 AI 完成登录功能的实际案例。
需求背景: 做一个简单的邮箱+密码登录功能,用 Next.js 实现。
给 AI 的验收标准:
## 功能:邮箱密码登录
### 前置条件
- 技术栈:Next.js 15 App Router + TypeScript
- 使用 bcrypt 进行密码加密
- 使用 JWT 进行会话管理
### 验收标准
- [ ] AC1: Given 用户在登录页面,输入正确的邮箱和密码,When 点击「登录」,Then 系统返回 JWT token,页面跳转到 /dashboard
- [ ] AC2: Given 用户输入错误的密码,When 点击「登录」,Then 显示「邮箱或密码错误」(不区分是邮箱错还是密码错)
- [ ] AC3: Given 邮箱格式不正确(不含 @ 符号),When 点击「登录」,Then 前端校验拦截,显示「请输入有效的邮箱地址」
- [ ] AC4: Given 密码为空,When 点击「登录」,Then 前端校验拦截,显示「请输入密码」
- [ ] AC5: Given 用户连续 5 次输入错误密码,When 第 6 次尝试登录,Then 账户锁定 15 分钟,显示「账户已锁定,请 15 分钟后重试」
- [ ] AC6: Given 用户账户已锁定,When 使用正确密码登录,Then 仍然显示「账户已锁定」
- [ ] AC7: Given 登录请求超时(>10 秒),Then 显示「请求超时,请稍后重试」
- [ ] AC8: 密码字段在前端做 input type="password" 处理
- [ ] AC9: JWT token 存储在 httpOnly cookie 中,不存储在 localStorage
- [ ] AC10: 登录成功后,后端不返回密码字段(即使是 hash 后的)
### 不要做
- 不做社交登录(Google/GitHub)
- 不做「记住我」功能
- 不做手机验证码登录这份验收标准直接作为 prompt 交给 AI。注意几个关键点:
- 每条 AC 都是可测试的——不存在「登录要快」「体验要好」这种无法验证的描述
- 安全相关的要求明确写出——AC9 和 AC10 是安全约束,不写的话 AI 可能会把 token 存到 localStorage
- 异常路径和边界条件——AC5-AC7 覆盖了锁定和超时场景
- 「不要做」同样重要——明确告诉 AI 不要做什么,避免它「好心办坏事」加一堆不需要的功能
常见错误和避坑指南
| 错误类型 | 表现 | 改进方式 |
|---|---|---|
| 过于模糊 | 「系统要稳定」「体验要好」 | 用具体数字量化:「99.9% 可用性」「首屏 ≤2s」 |
| 过于具体 | 「按钮颜色为 #3B82F6,圆角 8px」 | 验收标准描述行为,不描述样式细节(那是设计稿的事) |
| 缺少异常路径 | 只写正常操作流程 | 每个功能至少补充 2-3 条异常场景的 AC |
| 一条 AC 测多件事 | 「用户可以注册并登录」 | 拆分为独立的注册 AC 和登录 AC |
| 包含实现细节 | 「调用 /api/login 接口,返回 200」 | 描述用户可观察的行为,不描述内部实现 |
| 使用被动语态 | 「密码被验证」 | 改为「系统验证密码」 |
| 主观判断 | 「界面美观」「操作流畅」 | 改为可度量的指标或去掉 |
检查清单
写完验收标准后,对照以下清单逐条检查:
- 每条验收标准都是可测试的(可以明确判断通过或失败)
- 使用了 Given-When-Then 或其他结构化格式
- 覆盖了正常路径(用户正确操作的场景)
- 覆盖了异常路径(输入错误、权限不足、网络异常等)
- 没有使用模糊的形容词(快速、大量、好看)
- 每条 AC 只验证一件事(可以独立测试)
- 前置条件(Given)写清楚了初始状态
- 期望结果(Then)是具体可观察的
- 用主动语态描述了系统行为
- 明确写了「不做什么」(范围边界)
- 包含了非功能性需求(性能、安全、兼容性)
- 验收标准和用户故事一一对应
- 团队成员(包括测试)对每条 AC 的理解一致
- AI 编程场景下,AC 已经转化为可执行的检查格式(如 checkbox)
- 没有混入实现细节(不指定具体的技术实现方式)
小结
验收标准是需求文档中最「实战」的部分。功能列表告诉你「要做什么」,用户故事告诉你「为谁做」,而验收标准告诉你「做到什么程度算完」。
写好验收标准的核心原则可以浓缩为四条:
- 可测试:每条 AC 都能被验证,有明确的通过/失败判定
- 结构化:用 Given-When-Then 等格式,让每条 AC 都有清晰的上下文
- 分层写:系统级 → 页面级 → 功能级,从宏观到微观逐步细化
- 面向 AI:在 AI 编程场景下,验收标准同时是指令、约束和测试用例
记住:需求写得再好,如果无法验证,就不是需求——只是愿望。
参考资料
- Given-When-Then — Agile Alliance Glossary
- Acceptance Criteria: Purposes, Formats, and Best Practices — AltexSoft
- Given When Then Framework: A Step-by-Step Guide — Miro
- What is Acceptance Criteria? Definition, Examples, & Tips — Atlassian
- 19 Acceptance Criteria Examples for Product — ProdPad
- Acceptance Criteria: What It Is, and Best Practices — Zenhub
- How to Write Acceptance Criteria — 腾讯云开发者社区
- AI Coding Acceptance Criteria — spec-coding.dev