从需求分析到测试用例:用 ChatGPT、Claude、Gemini、DeepSeek 辅助接口开发的一套流程
在实际开发中,很多 Bug 并不是写代码时才产生的,而是在需求理解阶段就已经埋下了。
例如产品文档里写了一句:
用户可以提交退款申请,系统需要校验订单状态,并在退款成功后更新订单信息。
这句话看起来很简单,但真正落到接口开发时,会冒出一堆问题:
- 哪些订单状态允许退款?
- 已发货订单能不能退款?
- 已退款订单重复提交怎么办?
- 退款金额是否允许部分退款?
- 退款失败后订单状态是否回滚?
- 是否需要记录退款流水?
- 是否需要通知支付系统?
- 接口是同步返回还是异步处理?
- 测试用例要覆盖哪些边界?
如果这些问题没有在开发前拆清楚,后面就容易出现需求返工、接口改动、测试遗漏和线上异常。
这篇文章分享一种比较实用的做法:
把 ChatGPT、Claude、Gemini、DeepSeek 等大模型用于“需求澄清、接口设计、异常场景梳理、测试用例生成”这条链路中,而不是只让 AI 写代码。
重点不是让 AI 替代开发者,而是用它减少遗漏,提高需求到测试之间的信息一致性。
本文适合谁
本文更适合下面几类读者:
- 后端开发:需要根据需求拆接口、写 Service、处理异常状态;
- 前端开发:需要理解接口字段、异常返回和页面交互状态;
- 测试工程师:需要根据需求和接口设计补测试用例;
- 产品经理:希望提前发现需求描述里的模糊点;
- 技术负责人:希望团队在开发前形成统一的需求分析流程;
- 刚开始使用 AI 编程助手的开发者:想知道除了写代码,AI 还能怎么用。
示例会偏后端接口开发,但方法同样适用于前端页面、管理后台、数据处理任务和内部系统开发。
本次场景:退款申请接口
假设我们要开发一个退款申请接口。
原始需求如下:
用户可以对已支付订单提交退款申请。系统需要校验订单状态,如果符合条件,则创建退款记录,并将订单状态更新为退款处理中。
这个需求看起来明确,但开发时仍然不够用。
我们可以先让 AI 帮忙做第一轮需求拆解。
第一步:让 AI 找出需求里的不明确点
很多人一上来就问:
text
帮我设计一个退款接口。
这个问法太泛,模型容易直接输出接口路径、参数和代码,反而跳过了需求澄清。
更推荐先让 AI 站在开发、测试和产品的角度找问题。
Prompt 示例
text
你是一名有经验的后端开发和测试工程师,请帮我分析下面这段需求中存在的不明确点。
需求:用户可以对已支付订单提交退款申请。系统需要校验订单状态,如果符合条件,则创建退款记录,并将订单状态更新为退款处理中。
请从以下角度分析:1. 业务规则不明确的地方;2. 接口参数需要补充的地方;3. 状态流转需要确认的地方;4. 异常场景需要确认的地方;5. 测试用例可能遗漏的地方。
要求:- 不要直接写代码;- 用问题清单形式输出;- 每个问题说明为什么需要确认。
可能得到的输出方向
AI 通常会帮你列出类似问题:
| 分类 | 需要确认的问题 | 原因 |
|---|---|---|
| 订单状态 | 只有已支付订单可退款吗?已发货、已完成是否允许? | 影响状态校验逻辑 |
| 重复提交 | 同一订单是否允许多次退款? | 影响幂等和唯一约束 |
| 退款金额 | 是否支持部分退款? | 影响金额参数和校验 |
| 退款原因 | 是否必填?长度限制是多少? | 影响接口参数校验 |
| 支付系统 | 是否需要调用第三方退款接口? | 影响同步/异步流程 |
| 状态更新 | 创建退款记录和更新订单状态是否在同一事务? | 影响数据一致性 |
| 异常处理 | 创建退款记录成功但更新订单失败怎么办? | 影响回滚策略 |
| 权限校验 | 用户是否只能退自己的订单? | 影响安全边界 |
| 测试覆盖 | 是否需要覆盖并发重复提交? | 影响测试设计 |
这一步非常有价值。
因为 AI 不一定知道最终答案,但它可以帮你提前发现“还没问清楚”的问题。
第二步:把需求整理成接口规则
当需求问题确认后,可以让 AI 帮忙整理成接口设计草稿。
假设我们和产品确认了以下规则:
- 只有
PAID状态的订单允许提交退款; - 同一订单同一时间只能有一条进行中的退款申请;
- 暂不支持部分退款;
- 退款原因必填,长度不超过 200;
- 用户只能对自己的订单申请退款;
- 创建退款记录和订单状态更新必须在同一事务中完成;
- 接口只提交申请,不直接调用支付退款;
- 退款后订单状态改为
REFUNDING。
这时可以继续让 AI 输出接口草稿。
Prompt 示例
text
请根据下面确认后的业务规则,设计一个退款申请接口草稿。
业务规则:1. 只有 PAID 状态的订单允许提交退款;2. 同一订单同一时间只能有一条进行中的退款申请;3. 暂不支持部分退款;4. 退款原因必填,长度不超过 200;5. 用户只能对自己的订单申请退款;6. 创建退款记录和订单状态更新必须在同一事务中完成;7. 接口只提交申请,不直接调用支付退款;8. 退款后订单状态改为 REFUNDING。
请输出:- 接口路径;- 请求方法;- 请求参数;- 响应字段;- 业务校验顺序;- 可能的错误码;- 需要注意的数据一致性问题。
要求:- 不要输出完整代码;- 输出要适合后端开发和测试共同评审。
接口设计草稿示例
text
接口路径:POST /api/orders/{orderId}/refunds
请求参数:- orderId:订单 ID,路径参数,必填- reason:退款原因,字符串,必填,最大长度 200
响应字段:- success:是否成功- code:业务状态码- message:提示信息- refundId:退款申请 ID
业务校验顺序:1. 校验用户登录态;2. 校验 orderId 是否合法;3. 查询订单是否存在;4. 校验订单是否属于当前用户;5. 校验订单状态是否为 PAID;6. 校验是否已有进行中的退款申请;7. 创建退款记录;8. 更新订单状态为 REFUNDING;9. 返回退款申请结果。
这个结果不能直接当最终设计,但它很适合作为接口评审初稿。
第三步:让不同模型分别检查设计漏洞
单一模型容易按照你的输入“顺着说”。
对于状态流转、金额、并发、幂等这类问题,可以用多个模型交叉检查。
模型适配思路
| 模型 | 更适合的任务 | 在本场景中的用法 |
|---|---|---|
| ChatGPT | 通用需求分析、接口设计、代码草稿 | 生成第一版接口设计和校验顺序 |
| Claude | 长文档阅读、上下文一致性检查 | 检查需求描述和接口规则是否冲突 |
| Gemini | 快速结构化总结、表格化输出 | 生成错误码、测试点、评审清单 |
| DeepSeek | 中文业务逻辑分析、代码解释 | 分析状态流转、异常场景和后端实现风险 |
可以把同一份接口草稿分别交给不同模型,让它们只做“挑错”。
Prompt 示例
text
请你不要重新设计接口,只检查下面这个退款申请接口设计是否存在遗漏或风险。
重点检查:1. 状态流转是否完整;2. 是否存在重复提交问题;3. 是否存在并发问题;4. 是否存在权限问题;5. 是否存在事务一致性问题;6. 错误码是否足够表达业务失败原因;7. 测试用例是否可能遗漏。
输出格式:- 风险点- 风险等级:高 / 中 / 低- 原因- 建议补充的规则
这种问法比“帮我优化一下”更适合工程评审,因为它会迫使模型从风险角度输出。
第四步:把接口规则转成后端伪代码
在需求规则和接口设计都比较清楚之后,再让 AI 生成代码草稿会更靠谱。
但仍然建议先生成伪代码,而不是直接生成完整实现。
Prompt 示例
text
请根据下面的退款申请接口规则,生成 Java 后端 Service 层伪代码。
要求:1. 使用事务;2. 明确业务校验顺序;3. 不需要写 Controller;4. 不需要写 Repository 具体实现;5. 不要引入复杂架构;6. 每一步用注释说明目的。
业务规则:- 只有 PAID 状态订单允许申请退款;- 用户只能操作自己的订单;- 同一订单不能重复创建进行中的退款申请;- 创建退款记录和更新订单状态必须保持一致;- 成功后订单状态变为 REFUNDING。
伪代码示例
java
@Transactionalpublic RefundApplyResult applyRefund(Long userId, Long orderId, String reason) { // 1. 参数校验 if (userId == null || orderId == null) { return RefundApplyResult.invalidParam(); }
if (reason == null || reason.trim().isEmpty() || reason.length() > 200) { return RefundApplyResult.invalidReason(); }
// 2. 查询订单 Order order = orderRepository.findById(orderId); if (order == null) { return RefundApplyResult.orderNotFound(); }
// 3. 权限校验:只能申请自己的订单 if (!order.getUserId().equals(userId)) { return RefundApplyResult.noPermission(); }
// 4. 状态校验 if (!OrderStatus.PAID.equals(order.getStatus())) { return RefundApplyResult.invalidOrderStatus(); }
// 5. 检查是否已有进行中的退款申请 boolean existsProcessingRefund = refundRepository.existsProcessingRefund(orderId);
if (existsProcessingRefund) { return RefundApplyResult.duplicateRefund(); }
// 6. 创建退款记录 Refund refund = new Refund(); refund.setOrderId(orderId); refund.setUserId(userId); refund.setReason(reason); refund.setStatus(RefundStatus.PROCESSING); refund.setCreateTime(LocalDateTime.now()); refundRepository.save(refund);
// 7. 更新订单状态 order.setStatus(OrderStatus.REFUNDING); order.setUpdateTime(LocalDateTime.now()); orderRepository.save(order);
// 8. 返回结果 return RefundApplyResult.success(refund.getId());}
这段伪代码的作用是帮助开发者整理逻辑顺序。
真正落地时,还要继续考虑:
- 并发下两次请求同时通过
existsProcessingRefund; - 是否需要数据库唯一索引;
- 是否需要乐观锁;
- 是否需要状态更新条件;
- 事务回滚规则;
- 退款记录状态是否应该叫
APPLYING或PROCESSING; - 返回对象是否符合项目统一规范。
第五步:重点检查并发和幂等
退款申请接口虽然不像秒杀库存那样高并发,但仍然可能出现重复提交。
例如用户连续点击两次按钮,或者前端请求重试,都可能导致两个请求同时进入后端。
下面这段逻辑存在典型竞态条件:
java
boolean existsProcessingRefund = refundRepository.existsProcessingRefund(orderId);
if (existsProcessingRefund) { return RefundApplyResult.duplicateRefund();}
refundRepository.save(refund);
两个请求同时查询,都发现没有进行中的退款申请,然后都创建成功。
更稳妥的处理思路
常见做法包括:
- 数据库增加唯一约束;
- 使用订单状态条件更新;
- 增加幂等请求号;
- 对关键状态流转做乐观锁控制。
例如可以让 AI 帮忙检查并发风险,但不要直接让它决定最终方案。
Prompt 示例
text
请分析下面退款申请逻辑在并发重复提交时是否存在问题。
代码逻辑:1. 查询订单;2. 判断订单状态是否为 PAID;3. 查询是否已有进行中的退款申请;4. 创建退款申请;5. 更新订单状态为 REFUNDING。
请回答:- 是否可能重复创建退款申请;- 哪一步存在竞态条件;- 数据库层可以增加什么约束;- 应用层可以增加什么保护;- 哪些测试用例可以验证该问题。
可能的改进方向
例如数据库层可以增加约束:
sql
-- 示例:具体语法需要根据数据库类型调整CREATE UNIQUE INDEX uk_refund_order_processingON refund(order_id, status);
但这个索引是否合理,要看 status 的取值和历史退款记录保留策略。
如果一个订单未来可能有多次不同状态的退款记录,唯一索引设计就要更加谨慎。
也可以通过订单状态条件更新降低竞态风险:
java
@Modifying@Query("update Order o set o.status = :targetStatus " + "where o.id = :orderId and o.status = :sourceStatus")int updateStatusIfMatch(@Param("orderId") Long orderId, @Param("sourceStatus") OrderStatus sourceStatus, @Param("targetStatus") OrderStatus targetStatus);
Service 中根据更新行数判断是否成功:
java
int updated = orderRepository.updateStatusIfMatch( orderId, OrderStatus.PAID, OrderStatus.REFUNDING);
if (updated == 0) { return RefundApplyResult.invalidOrderStatus();}
这种方式可以避免多个请求同时把同一个订单从 PAID 推进到 REFUNDING。
但具体是先创建退款记录,还是先更新订单状态,需要结合业务事务和失败回滚策略评审。
第六步:让 AI 生成测试用例,而不是只写正常流程
需求到测试用例的转换,是 AI 很适合参与的环节。
Prompt 示例
text
请根据下面退款申请接口规则生成测试用例。
接口规则:1. 用户只能对自己的订单申请退款;2. 只有 PAID 状态订单允许申请退款;3. 退款原因必填,长度不超过 200;4. 同一订单不能重复提交进行中的退款申请;5. 创建退款记录后,订单状态更新为 REFUNDING;6. 接口只提交退款申请,不直接执行支付退款。
输出格式:- 用例编号- 测试场景- 前置条件- 输入数据- 预期结果- 优先级- 是否需要自动化
测试用例示例
| 用例编号 | 测试场景 | 前置条件 | 预期结果 | 优先级 |
|---|---|---|---|---|
| TC001 | 正常申请退款 | 订单属于当前用户,状态为 PAID | 创建退款记录,订单变为 REFUNDING | 高 |
| TC002 | 订单不存在 | orderId 不存在 | 返回订单不存在 | 高 |
| TC003 | 操作他人订单 | 订单不属于当前用户 | 返回无权限 | 高 |
| TC004 | 未支付订单退款 | 订单状态为 CREATED | 返回状态不允许 | 高 |
| TC005 | 已退款订单重复申请 | 订单状态为 REFUNDED | 返回状态不允许 | 高 |
| TC006 | 退款原因为空 | reason 为空 | 返回参数错误 | 中 |
| TC007 | 退款原因超过 200 字 | reason 长度 201 | 返回参数错误 | 中 |
| TC008 | 重复点击退款按钮 | 同一订单连续提交两次 | 只允许一次成功 | 高 |
| TC009 | 并发重复提交 | 同一用户并发请求同一订单 | 只创建一条退款申请 | 高 |
| TC010 | 创建退款记录失败 | 模拟数据库异常 | 订单状态不应被错误更新 | 高 |
| TC011 | 更新订单状态失败 | 模拟更新失败 | 事务回滚或返回明确失败 | 高 |
| TC012 | 未登录访问 | 无有效用户上下文 | 返回未登录或无权限 | 高 |
AI 生成的测试用例通常能覆盖大部分常规场景。
但业务相关的特殊规则仍然需要人工补充,例如:
- 超过售后期是否允许退款;
- 虚拟商品是否允许退款;
- 组合订单如何退款;
- 优惠券、积分、余额如何处理;
- 部分退款是否影响发票;
- 退款失败是否允许重新申请。
第七步:让 AI 输出接口文档初稿
当接口规则、伪代码和测试点都比较清楚后,可以让 AI 整理接口文档。
Prompt 示例
text
请根据下面信息生成一份接口文档初稿。
接口:申请退款路径:POST /api/orders/{orderId}/refunds
业务规则:- 用户只能对自己的订单申请退款;- 只有 PAID 状态订单允许申请退款;- 退款原因必填,长度不超过 200;- 成功后创建退款记录,并将订单状态改为 REFUNDING;- 接口不直接调用支付退款。
请输出:1. 接口说明;2. 请求路径;3. 请求方法;4. 请求参数;5. 响应示例;6. 错误码;7. 状态流转;8. 注意事项。
文档片段示例
json
{ "success": true, "code": "SUCCESS", "message": "退款申请提交成功", "data": { "refundId": 10086, "orderStatus": "REFUNDING" }}
错误码可以整理成表格:
| 错误码 | 含义 | 说明 |
|---|---|---|
| ORDER_NOT_FOUND | 订单不存在 | orderId 无效或订单已删除 |
| NO_PERMISSION | 无权限 | 订单不属于当前用户 |
| INVALID_ORDER_STATUS | 订单状态不允许退款 | 非 PAID 状态 |
| INVALID_REFUND_REASON | 退款原因不合法 | 空值或长度超过限制 |
| DUPLICATE_REFUND | 重复退款申请 | 已存在进行中的退款 |
| SYSTEM_ERROR | 系统异常 | 数据库或服务异常 |
这类文档初稿通常比从零写快很多。
不过最终文档仍然要由开发、测试和产品确认。
如何验证 AI 输出是否可靠
AI 辅助需求分析和测试用例生成时,最重要的是验证。
建议至少做下面几类检查。
1. 和产品需求逐条对齐
检查 AI 输出是否新增了未经确认的规则。
例如 AI 可能会主动加入“超过 7 天不能退款”,但需求里并没有这个规则。
这类内容不能直接采纳,需要单独确认。
2. 和数据库约束对齐
检查 AI 建议的唯一索引、状态字段、金额字段是否符合现有表结构。
不要因为 AI 给了一个看起来合理的 SQL,就直接改生产表结构。
3. 和项目异常规范对齐
每个项目的错误码、异常处理、返回结构都不一样。
AI 生成的错误码只能作为草稿,需要改成项目统一格式。
4. 用测试验证关键风险
尤其是:
- 并发重复提交;
- 状态流转;
- 事务回滚;
- 权限控制;
- 参数边界;
- 历史数据兼容。
这些不能只靠模型判断。
5. 做安全和隐私检查
不要把真实用户数据、订单号、手机号、支付流水号、内部接口地址等直接输入给模型。
如果要分析日志或代码,建议先脱敏。
常见误区
1. 直接让 AI 写代码,跳过需求澄清
这是最常见的问题。
需求没拆清楚时,AI 生成的代码越完整,风险越大。
更合理的顺序应该是:
text
需求澄清 → 规则整理 → 接口设计 → 伪代码 → 测试用例 → 代码实现
2. 把 AI 补充的规则当成真实需求
AI 会根据常见业务经验补充规则,但这些规则不一定适合当前项目。
例如退款场景里,AI 可能自动补充售后期、退款金额、支付渠道等规则。
这些可以作为问题清单,但不能直接变成开发逻辑。
3. 只生成正常用例,不生成异常用例
接口测试里真正容易出问题的,通常不是正常流程,而是:
- 参数为空;
- 状态不允许;
- 重复提交;
- 并发请求;
- 权限不匹配;
- 数据库异常;
- 第三方服务失败。
Prompt 里要明确要求模型覆盖异常和边界。
4. 不限制输出格式
如果不限制格式,模型容易输出一大段解释文字,不方便落地。
建议明确要求表格、清单、JSON 示例、错误码表等结构化格式。
5. 忽略事务和并发
很多业务接口在单线程下看起来没问题,但一到并发场景就出错。
退款、库存、积分、优惠券、余额、审批流等场景尤其要注意。
一套可复用 Prompt 模板
最后整理一套可以直接改造使用的模板。
需求澄清模板
text
你是一名资深后端开发和测试工程师,请分析下面需求中的不明确点。
需求:粘贴需求内容
请从以下角度输出问题清单:1. 业务规则;2. 参数校验;3. 状态流转;4. 权限控制;5. 并发和幂等;6. 异常处理;7. 测试覆盖。
要求:- 不要写代码;- 每个问题说明为什么需要确认;- 输出为表格。
接口设计模板
text
请根据下面已确认的业务规则,生成接口设计草稿。
业务规则:粘贴规则
请输出:- 接口路径;- 请求方法;- 请求参数;- 响应字段;- 错误码;- 业务校验顺序;- 数据一致性注意事项。
要求:- 不要输出完整代码;- 输出适合开发和测试评审。
测试用例模板
text
请根据下面接口规则生成测试用例。
接口规则:粘贴规则
输出格式:- 用例编号;- 测试场景;- 前置条件;- 输入数据;- 预期结果;- 优先级;- 是否需要自动化。
要求:- 覆盖正常流程、异常流程、边界值、权限、并发和幂等;- 不要只输出正常用例。
风险检查模板
text
请检查下面接口设计是否存在风险。
接口设计:粘贴接口设计
重点检查:1. 状态流转;2. 数据一致性;3. 并发重复提交;4. 权限漏洞;5. 参数边界;6. 异常回滚;7. 测试遗漏。
输出格式:- 风险点;- 风险等级;- 原因;- 修改建议;- 是否必须修改。
总结
AI 在接口开发中的价值,不只是帮忙写代码。
更稳定、更实用的用法,是把它放到研发流程的前半段:
- 帮你发现需求不明确点;
- 帮你整理接口规则;
- 帮你生成错误码和校验顺序;
- 帮你检查状态流转和并发风险;
- 帮你生成测试用例;
- 帮你整理接口文档初稿。
对于 ChatGPT、Claude、Gemini、DeepSeek 这类模型,不必纠结哪个一定最好。
在研发场景里,更重要的是让模型输出可检查、可讨论、可验证的内容。
一句话总结:
AI 可以提高需求分析和测试设计的效率,但不能替代开发者对业务规则、系统边界和代码质量的最终判断。
更多推荐



所有评论(0)