【AI测试系统】第2篇:拒绝盲目 AI:规则引擎 10ms 自动生成 36 条测试用例实战(附源码)

0 阅读9分钟

AI测试系统系列会写28篇,这是第2篇,会持续更新

先说个反直觉的事:规则引擎比 AI 更适合作为用例生成的第一步

很多人一听"AI测试"就以为所有用例都是大模型生成的。实际上我们跑下来的经验是:规则引擎出基础用例,AI 做精细打磨,两者配合效率最高

原因很简单。规则引擎纯 Python 执行,10 毫秒级出几十条用例,成本为零,结构统一,适合快速评估测试工作量;AI 生成一条用例要 1-3 秒,成本几分钱,但能覆盖规则引擎想不到的边缘场景。先规则后 AI,相当于先用粗筛网捞一遍,再用精筛网补漏。

这篇先讲粗筛网——规则引擎怎么从需求文档名称自动提取功能点,每个功能点生成 3 个测试场景。


一、核心思路:关键词匹配 + 场景模板

规则引擎的输入是需求文档名称(比如"电商秒杀查询功能需求文档"),输出是测试用例列表。中间经过三步:

  1. 从文档名称提取功能点——匹配关键词,找到要测哪些功能
  2. 按功能点名称去重——合并重复项,保留唯一功能点
  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 只保留真正核心的流程。


七、工程建议

如果你要在自己的项目里落地类似的规则引擎,以下几点经验供参考:

  1. feature_map 建议抽离到配置文件(JSON/YAML),不要硬编码在 Python 文件里。这样业务人员也能直接编辑,不用改代码。
  2. 去重策略要统一:按功能点名称去重是最简单的方案。如果业务更复杂,可以考虑按「名称 + 模块」组合去重。
  3. 预留扩展点:在匹配逻辑里留一个 custom_rules 钩子,让特殊业务可以绕过关键词匹配,直接返回自定义功能点列表。
  4. 加单元测试:规则引擎看起来简单,但关键词交叉匹配时很容易出边界问题。建议至少覆盖:单关键词、多关键词、无匹配、兜底策略 4 种场景。
  5. 监控 feature_map 命中率:记录每次匹配命中了哪些关键词、走了多少次兜底策略。兜底比例过高(>30%)说明 feature_map 需要扩充了。

八、规则引擎的边界在哪里

规则引擎的优势是快、便宜、结构统一。但它的局限也很明显:

  • 只能覆盖预定义的关键词。遇到"元宇宙"、"Web3"这种新词,feature_map 里没有映射,只能走兜底策略。
  • 生成的用例不够具体。「执行正常操作流程」这种步骤描述,放之四海而皆准,但也意味着不够具体。真正执行的时候,测试工程师还是要手动细化。
  • 缺少业务深度。规则引擎不知道你的业务逻辑是什么,它只是按模板填空。真正的测试设计还需要测试工程师结合业务经验来补充。

所以我们的策略是:规则引擎出基础用例 → AI Skill 做精细打磨 → 测试工程师最终评审。三层过滤,效率和质量都有保障。


下篇预告:第3篇讲 LLM Skill 怎么调用大模型生成高质量用例——Prompt 设计、质量评分、容错处理,一个都不能少。