AI测试系统系列会写28篇,这是第2篇,会持续更新
先说个反直觉的事:规则引擎比 AI 更适合作为用例生成的第一步
很多人一听"AI测试"就以为所有用例都是大模型生成的。实际上我们跑下来的经验是:规则引擎出基础用例,AI 做精细打磨,两者配合效率最高。
原因很简单。规则引擎纯 Python 执行,10 毫秒级出几十条用例,成本为零,结构统一,适合快速评估测试工作量;AI 生成一条用例要 1-3 秒,成本几分钱,但能覆盖规则引擎想不到的边缘场景。先规则后 AI,相当于先用粗筛网捞一遍,再用精筛网补漏。
这篇先讲粗筛网——规则引擎怎么从需求文档名称自动提取功能点,每个功能点生成 3 个测试场景。
一、核心思路:关键词匹配 + 场景模板
规则引擎的输入是需求文档名称(比如"电商秒杀查询功能需求文档"),输出是测试用例列表。中间经过三步:
- 从文档名称提取功能点——匹配关键词,找到要测哪些功能
- 按功能点名称去重——合并重复项,保留唯一功能点
- 为每个功能点生成 3 个场景——正常流程、异常处理、边界条件
整个过程不依赖任何外部 API,纯 Python 代码,毫秒级完成。
二、功能点提取:从文档名称到功能列表
代码里维护了一个 feature_map,把业务关键词映射到功能点:
feature_map = {
'登录': [
{'name': '正常登录', 'module': '登录模块', 'priority': 'P0'},
{'name': '错误密码处理', 'module': '登录模块', 'priority': 'P1'},
{'name': '账号锁定机制', 'module': '登录模块', 'priority': 'P1'},
{'name': '忘记密码流程', 'module': '登录模块', 'priority': 'P2'},
],
'订单': [
{'name': '创建订单', 'module': '订单模块', 'priority': 'P0'},
{'name': '订单取消', 'module': '订单模块', 'priority': 'P1'},
{'name': '订单查询', 'module': '订单模块', 'priority': 'P2'},
{'name': '订单修改', 'module': '订单模块', 'priority': 'P2'},
],
'查询': [
{'name': '商品列表查询', 'module': '商品查询', 'priority': 'P0'},
{'name': '秒杀活动查询', 'module': '秒杀查询', 'priority': 'P0'},
{'name': '订单列表查询', 'module': '订单查询', 'priority': 'P0'},
# ... 共 12 个查询相关功能点
],
# 还有 '支付'、'商品'、'用户'、'电商'、'秒杀'、'财务' 等关键词(共 10 个)
}
匹配逻辑是按优先级顺序遍历关键词列表:
priority_keywords = ['查询', '电商', '秒杀', '财务', '商品', '订单', '支付', '用户', '登录']
for keyword in priority_keywords:
if keyword in base_name: # base_name = doc_name.lower(),兼容英文文档名
matched_features.extend(feature_map.get(keyword, []))
为什么要排优先级?因为一个文档名称可能匹配多个关键词。比如"电商秒杀查询需求"同时命中"查询"、"电商"、"秒杀"三个关键词。按优先级顺序匹配,确保更具体的关键词优先被选中。
去重逻辑(关键一步):
# 按功能点名称去重,保留第一次出现的优先级
seen = set()
unique_features = []
for f in matched_features:
if f['name'] not in seen:
seen.add(f['name'])
unique_features.append(f)
matched_features = unique_features
如果所有关键词都没命中,兜底策略上场:
if not matched_features:
if '需求' in doc_name:
matched_features = [
{'name': '功能完整性测试', 'module': '需求验证', 'priority': 'P0'},
{'name': '业务流程测试', 'module': '需求验证', 'priority': 'P0'},
{'name': '异常场景测试', 'module': '需求验证', 'priority': 'P1'},
{'name': '边界条件测试', 'module': '需求验证', 'priority': 'P2'},
]
else:
matched_features = [
{'name': '核心功能流程', 'module': '核心模块', 'priority': 'P0'},
{'name': '异常处理流程', 'module': '核心模块', 'priority': 'P1'},
{'name': '边界条件测试', 'module': '核心模块', 'priority': 'P2'},
{'name': '用户体验测试', 'module': '核心模块', 'priority': 'P3'},
]
三、场景模板:每个功能点生成 3 条用例
拿到功能点列表后,为每个功能点套用 3 个场景模板:
test_scenarios = [
{
'suffix': '正常流程',
'type': '功能测试',
'preconditions': '用户已登录且权限充足',
'steps': ['进入功能页面', '执行正常操作流程', '填写必要的输入信息', '提交操作', '验证系统响应'],
'expected': '系统正确处理请求并返回预期结果'
},
{
'suffix': '异常处理',
'type': '异常测试',
'preconditions': '用户已登录',
'steps': ['进入功能页面', '输入无效的测试数据', '执行操作', '观察系统错误处理', '验证错误提示'],
'expected': '系统正确捕获异常并显示友好的错误提示'
},
{
'suffix': '边界条件',
'type': '边界测试',
'preconditions': '用户已登录',
'steps': ['进入功能页面', '输入边界值数据(最大值/最小值)', '执行操作', '验证系统处理结果'],
'expected': '系统正确处理边界值,不出现崩溃或数据错误'
}
]
正常流程验证系统"能做对",异常处理验证系统"能容错",边界条件验证系统"能扛住"。三个场景覆盖软件测试最核心的三个维度。
每个功能点 × 3 个场景 = 最终用例数。比如「电商秒杀查询需求」匹配到 20 个功能点(含重复),按名称去重后为 12 个,12 × 3 = 36 条用例。
四、实战走一遍
输入文档名称:"电商秒杀查询功能需求文档"
匹配结果:
- '查询' → 12 个查询相关功能点
- '电商' → 4 个电商相关功能点
- '秒杀' → 4 个秒杀相关功能点
- 去重后共 12 个功能点
生成用例(前 6 条 + 最后 3 条):
| 编号 | 名称 | 模块 | 优先级 | 类型 |
|---|---|---|---|---|
| TC001 | 商品列表查询 - 正常流程 | 商品查询 | P0 | 功能测试 |
| TC002 | 商品列表查询 - 异常处理 | 商品查询 | P0 | 异常测试 |
| TC003 | 商品列表查询 - 边界条件 | 商品查询 | P0 | 边界测试 |
| TC004 | 秒杀活动列表查询 - 正常流程 | 秒杀查询 | P0 | 功能测试 |
| TC005 | 秒杀活动列表查询 - 异常处理 | 秒杀查询 | P0 | 异常测试 |
| TC006 | 秒杀活动列表查询 - 边界条件 | 秒杀查询 | P0 | 边界测试 |
| ... | ... | ... | ... | ... |
| TC034 | 边界条件测试 - 正常流程 | 通用查询 | P2 | 功能测试 |
| TC035 | 边界条件测试 - 异常处理 | 通用查询 | P2 | 异常测试 |
| TC036 | 边界条件测试 - 边界条件 | 通用查询 | P2 | 边界测试 |
12 个功能点 × 3 个场景 = 36 条用例,纯 Python 执行,无需调用任何外部 API。
五、规则引擎 vs AI 生成:对比一览
| 维度 | 规则引擎 | AI 生成 |
|---|---|---|
| 生成速度 | 10 毫秒级 | 1-3 秒/条 |
| 成本 | 零(纯本地) | 几分钱/条(API 调用) |
| 用例数量 | 固定(功能点数 × 3) | 灵活(可指定数量) |
| 用例质量 | 结构化但通用 | 针对性强、更具体 |
| 覆盖范围 | 仅预定义关键词 | 可理解任意业务场景 |
| 可维护性 | 需手动维护 feature_map | 只需改 Prompt |
| 适用场景 | 快速评估、批量初筛 | 精细打磨、边缘场景 |
结论:两者不是替代关系,而是互补关系。规则引擎负责"广度",AI 负责"深度"。
六、踩过的坑
坑 1:功能点重复。「电商秒杀查询」同时命中三个关键词,同一个功能点被添加了多次(比如「订单查询」同时出现在「订单」和「查询」的映射里)。加上按名称去重逻辑后解决。
坑 2:关键词不够用。项目初期只有 9 个关键词,后来接了「物流」、「营销」、「客服」等新模块,feature_map 从 9 个扩展到了 10 个。规则引擎的通病——维护成本随业务增长而上升。
坑 3:优先级分配不够细。P0 全给了核心功能,但实际测试中 P0 用例太多(占了 40%),资源分配不过来。后来调整了策略,把部分 P0 降为 P1,让 P0 只保留真正核心的流程。
七、工程建议
如果你要在自己的项目里落地类似的规则引擎,以下几点经验供参考:
- feature_map 建议抽离到配置文件(JSON/YAML),不要硬编码在 Python 文件里。这样业务人员也能直接编辑,不用改代码。
- 去重策略要统一:按功能点名称去重是最简单的方案。如果业务更复杂,可以考虑按「名称 + 模块」组合去重。
- 预留扩展点:在匹配逻辑里留一个
custom_rules钩子,让特殊业务可以绕过关键词匹配,直接返回自定义功能点列表。 - 加单元测试:规则引擎看起来简单,但关键词交叉匹配时很容易出边界问题。建议至少覆盖:单关键词、多关键词、无匹配、兜底策略 4 种场景。
- 监控 feature_map 命中率:记录每次匹配命中了哪些关键词、走了多少次兜底策略。兜底比例过高(>30%)说明 feature_map 需要扩充了。
八、规则引擎的边界在哪里
规则引擎的优势是快、便宜、结构统一。但它的局限也很明显:
- 只能覆盖预定义的关键词。遇到"元宇宙"、"Web3"这种新词,feature_map 里没有映射,只能走兜底策略。
- 生成的用例不够具体。「执行正常操作流程」这种步骤描述,放之四海而皆准,但也意味着不够具体。真正执行的时候,测试工程师还是要手动细化。
- 缺少业务深度。规则引擎不知道你的业务逻辑是什么,它只是按模板填空。真正的测试设计还需要测试工程师结合业务经验来补充。
所以我们的策略是:规则引擎出基础用例 → AI Skill 做精细打磨 → 测试工程师最终评审。三层过滤,效率和质量都有保障。
下篇预告:第3篇讲 LLM Skill 怎么调用大模型生成高质量用例——Prompt 设计、质量评分、容错处理,一个都不能少。