本文作者是「测试套件」功能的产品负责人,旨在分享该功能背后的设计思路,包括我们为什么这样设计产品、决策的理由是什么。欢迎所有关心 Apifox 产品设计理念的朋友阅读了解&讨论。
“我有 200 个用例,但发版只想跑其中 20 个”
先说一些我们经常听到的真实用户反馈。

你会不会有同样的想法?或者你是不是也有印象在我们的群里看到类似的言论?
这些需求有一个共同点:用户不是要“运行用例”,而是要“按条件组织用例,然后运行”。
现有的功能是按“用例”维度设计的——你选择用例,然后运行。但用户需要的是按“规则”维度:告诉系统一个条件,符合条件的用例自动执行。

回看我们的现状
场景用例是我们自动化测试能力的核心。它允许你自由编排多个接口请求,按照真实的业务流程顺序执行——登录、创建订单、支付、查询订单状态。这套能力我们打磨了很长时间,用户反馈也相当正向。围绕场景用例,我们还提供了丰富的运行方式:
- 按目录批量运行:选择目录 - 在目录中再选择想要运行的场景用例,然后批量运行目录中所有被选中的用例;
- CLI 与流水线集成:通过命令行工具接入 CI/CD,代码合并自动触发测试;
- 定时任务:设置定时器,根据定时器触发自动执行巡检;
这些能力覆盖了“怎么跑”的问题。但用户的需求并没有完全被满足。所以我们收到了上面的那些吐槽。
自动化测试的两个层次
我们一直在思考:如何让用户在 Apifox 上完成从 API 设计、开发、调试到测试的完整闭环?
设计阶段有 API 文档,开发阶段有 Mock 服务,调试阶段有接口测试,那测试阶段呢?场景用例解决了“如何编排一个完整的业务流程”,但没有解决“如何在不同阶段、不同需求下灵活组织测试范围”。
于是我们把自动化测试的需求拆分为两个层次:
| 层次 | 核心问题 | 对应功能 |
|---|---|---|
| 编排层 | 如何把多个接口按业务流程串起来? | 场景用例 |
| 执行层 | 如何按条件灵活选择“跑哪些用例”? | 测试套件 |
- 场景用例是“造积木”:你定义每一块积木长什么样(一个完整的业务流程)。
- 测试套件是“搭积木”:你决定这次要用哪些积木搭成什么形状(按条件筛选、组合、执行)。
两者不是替代关系,而是分层协作。场景用例管“内容”,测试套件管“组织和执行”。以上就是测试套件这个新资源类型诞生的背景。

一、静态还是动态?
在设计测试套件时,我们面临一个根本性的问题:
用户把用例加入套件后,套件里的内容是固定的,还是会跟着变化的?
场景一:冒烟测试——软件行业的“健康体检”
“冒烟测试”这个词来自硬件行业:给一块新电路板通电,如果没有冒烟,说明起码没有短路,可以进行下一步测试。
在软件行业,冒烟测试的核心思想是:用最小的成本验证系统是否“基本正常”。它不追求覆盖所有功能,只验证最核心的业务路径——用户能登录吗?能下单吗?能支付吗?
冒烟测试有几个典型特点:
- 用例数量少但精选:通常只有 5-15 个核心场景
- 变动频率低:经过评审确定,不会轻易增删
- 执行频率高:每次代码提交都可能触发
这种场景需要“静态模式”:我指定了哪些用例,就永远跑这些用例,除非我手动修改。
场景二:按模块回归——用规则代替人工维护
假设你负责支付模块,有一个文件夹叫“支付功能”,里面有 50 个用例。每周可能新增几个,也可能删除几个。你希望每次回归都覆盖这个模块下的所有用例,不用每次都去检查有没有新增的。
这种场景需要“动态模式”:我告诉系统一个规则(支付功能目录下的所有用例),系统每次运行时自动匹配。这个设计在 AI 时代尤为重要。 随着 Copilot、Cursor 等 AI 编程工具的普及,代码生成的速度在加快,测试用例的产出也在提速。如果每次新增用例都要手动维护回归列表,维护成本会随着 AI 生产力的提升而线性增长。动态模式让用例的“生产”和“组织”解耦——你只管写用例,套件会自动把符合条件的新用例纳入进来。

我们的决定
经过长时间研究、收集用户反馈与调研,我们认为两种模式都是真实需求,我们选择都支持。
但这带来一个用户体验问题:选项太多会让人困惑。所以,在产品界面的设计上,我们加上了很多的思考:
- 不过于强调“静态”和“动态”这两个词: 对用户来说,这是引入了新的概念,可能会有一定的理解成本,所以不能在界面上过于强调这两个概念,并且不能在使用的位置只暴露这两个概念文案,这样会增加用户思考,带来较差的体验。
- 用操作和界面元素引导: 当用户选择“静态”时,右侧的详情列表会出现复选框引导用户要选择具体的接口、场景用例,并且最后一步确认按钮会明确告知“选择 X 个选项”;当用户选择“动态”时,右侧的详情列表仅是只读模式,不可选择其中的一部分,从而告知用户你是在使用“这个条件下的全部内容”。
- 文字介绍辅助: “后续如有新增且符合当前条件的用例,会自动加入”这些文案,会再次告知用户动态的意义,让用户知道这个套件会“活着”。
这样设计的好处是:用户不需要花过多的精力去思考与理解“静态”和“动态”的概念差异,阅读大量文本,只需要按自己的场景操作,在操作的过程中就自然而然的对这两个模式有个基本的理解。
二、统一配置还是各跑各的?
每个测试场景可能有自己的运行配置:用开发环境、测试环境还是预发环境?循环多少次?这些配置在创建场景时已经设置好了。现在把多个场景放到一个套件里,问题来了:用谁的配置?
用户的两种诉求
诉求 A:“我想让套件里的所有用例都跑测试环境,不管它们原来的配置是什么。”
这在全量回归时很常见。你希望有一个统一的“回归环境”,消除环境差异带来的干扰。
诉求 B:“每个场景跑自己的环境就行,我设置好了的。”
这在日常执行时很常见。支付服务跑支付测试环境,用户服务跑用户测试环境,配置早就设好了,没必要改。
我们的决定
这两种诉求看似矛盾,但我们发现可以用“**默认值 + 可选覆盖”**的模式来调和。
关键问题是:默认值选哪个?
默认情况下,每个场景按自己保存的配置运行(除了环境)——这是最“符合直觉”的行为。你之前怎么配的,现在还怎么跑。
环境配置会很特殊,因为在测试套件的运行配置里,是很直观可见的一个配置。而且针对不同类型的资源,使用环境的方法差别很大:
- 单接口用例:无论动态还是静态的单接口用例,环境都是使用套件指定的环境——跟单接口本身指定的环境方式一致,很好理解。
- 静态场景用例:在多数情况下,静态的场景用例都期望使用测试套件中的环境配置,所以我们为此情况单独设置了一个“继承自套件”的默认值——这样套件一切整个套件内的用例统一联动,方便使用。
- 动态场景用例:在多数情况下,动态的场景用例同样期望使用测试套件中的环境配置,所以默认是一套自定义的配置并且环境是继承套件中设置的环境。不过当然,如果你期望这些用例使用你已经在场景用例中编排设置好的各种配置,你可以选择从这些场景用例里面来继承运行配置实际运行。
如果用户需要统一配置,可以选择“使用相同配置运行”,然后指定一套独立配置。这个选项的位置放在“高级配置”里,不干扰常规使用路径。
并行执行,让你的套件快快跑
当测试套件增长到数百个时,串行执行会成为自动化交付的瓶颈。一个完整的回归测试可能需要一小时才能完成,这会延迟发布流程并减慢生产监控中的问题检测。

测试套件默认支持并行执行。只需在串行和并行模式之间一键切换——系统会根据运行机器可用资源自动确定最佳并发性。无需手动调整。这可以将60分钟的回归测试缩短至30分钟以下,而无需更改测试逻辑。
并行执行自动处理依赖隔离。每个场景都在自己的上下文中运行,确保一个场景的共享变量或环境状态不会干扰另一个场景。对于真正相互依赖的场景,你需要将其分组为具有顺序步骤的单个场景。

三、和目录批量运行的边界
Apifox 已经有“测试场景”的批量运行功能——在场景目录上右键,可以批量运行整个目录下的场景。
测试套件不就是换了个名字吗?有什么区别?
本质区别
- 场景目录是按“**物理结构”**组织的——你把用例放进哪个文件夹,就属于哪个分组。一个用例只能属于一个文件夹。
- 测试套件是按“**逻辑规则”**组织的——你定义一套筛选条件,符合条件的用例自动归入。一个用例可以同时属于多个套件。

举个 🌰:
- “支付模块回归套件”包含所有“支付”标签的 P0/P1 用例
- “全量冒烟套件”包含所有 P0 用例
- 某个用例如果同时是 P0 且带有“支付”标签,它会同时出现在两个套件里
这种灵活性是目录结构做不到的。
为什么还需要一个新的资源类型?
你可能会问:场景用例已经可以跑了,目录批量运行也有了,为什么还要专门做一个“测试套件”?
答案是:
我们在为“场景化测试”的未来做准备。
现代软件开发的一个趋势是:测试场景的数量随着 AI 生产代码会越来越多,但测试方法是会越来越标准化的。
想想看,你的团队可能面临这些情况:
- 日常开发:跑冒烟测试就够了;
- 版本发布:要跑全量回归;
- 紧急修复:只跑受影响模块的 P0 用例;
- 线上巡检:每小时检查核心接口;
- 灰度发布:对比新旧版本的接口响应。
这些场景对“跑哪些用例”的要求完全不同,但底层的用例是同一批。你只应该编排功能的业务流程并保存为一个个用例,为了“回归”这种测试的执行需求,从而编排一个用例来解决,这是不合逻辑、也不好维护的。

更重要的是,这种“积木化”的思路可以大幅降低测试环境的模拟成本。过去你可能需要为每个测试场景搭建专属的沙箱环境,现在你可以用同一套环境、同一批用例,只是组合方式不同。套件成为连接“测试资产”和“测试需求”的桥梁。
这就是我们做测试套件的真正意图:不只是让自动化测试 “能跑”,而是让自动化测试 “可复用”、“能按期望自动运行”。
| 功能 | 定位 | 适用场景 |
|---|---|---|
| 场景用例 | 业务场景的请求流程编排 | 自动化测试基础搭建、构成业务功能单元 |
| 场景目录 | 用例的物理归档位置 | 日常用例管理、团队协作 |
| 目录批量运行 | 快速跑一个目录下的所有用例 | 功能回归、全量回归、探索性测试 |
| 测试套件 | 可复用的测试执行单元 | 版本回归、冒烟测试、定期巡检 |
第一版暂时没做的事情
做产品需要取舍。以下是我们讨论过但决定暂时不做的功能:
1. 套件嵌套
- 场景:把多个套件组合成一个更大的套件。比如“全量回归”包含“支付模块回归”+“用户模块回归”+“订单模块回归”。
- 为什么暂时不做:增加复杂度,而动态模式已经能解决大部分需求。如果你想跑多个模块,可以用动态模式匹配更大范围的标签或目录。
- 如果用户确实需要:我们会观察数据,如果发现大量用户在创建内容高度重叠的套件,说明嵌套是真实需求,我们会重新评估。
❓ 你有“套件套套件”的需求吗?如果有,你的场景是什么?
2. 失败自动重试
- 场景:某个用例因为网络抖动失败了,自动重试一次。
- 为什么暂时不做:担心掩盖真实问题。如果一个接口偶发性失败,这本身可能就是需要关注的问题,而不是通过重试来“消除”。
- 如果后续做:可能会作为可选策略提供,并在报告中明确标注“重试后通过”,确保问题不被隐藏。
❓ 你觉得自动重试是必要的吗?你更希望看到“干净的结果”还是“真实的结果”?
写给正在读这篇文章的您
测试套件这个功能,从用户反馈到产品上线,我们思考了很多,也放弃了很多。但我们深知,真正好的产品不是设计出来的,而是用出来的。
我们可能漏掉了你最需要的功能,也可能把某个细节设计得让你用着别扭。这些问题,只有你告诉我们,我们才知道。
如果你试用了测试套件,欢迎告诉我们:
- 哪个设计让你觉得“终于有人懂我了”?
- 哪个操作让你卡住了、困惑了?
- 你还期待什么能力?
你的反馈会直接影响我们下一版的优先级排序(真心!)期待听到你的声音 🙌
如果你对功能背后的设计有任何疑问,欢迎加入我们的微信、飞书等各种 IM 群中讨论。