大家好,我是测试员周周。
前四篇文章,我讲了这套 AI 测试技能包的架构、用例生成、RAG 知识库、接口自动化自愈和 UI 定位自愈。
有读者在后台问我:"周周,你这些讲的都是功能测试。性能压测呢?是不是还得手写脚本?"
好问题。性能压测的脚本编写门槛一直比接口测试高——接口测试用 requests 库就行,但压测你要学 k6(基于 JavaScript 的压测工具)的语法、或者 JMeter(基于 GUI + XML 的传统压测工具)的操作、或者 Locust(基于 Python 协程的压测框架)。而且不同公司的技术栈不一样,有的用 k6、有的用 JMeter、有的用 Locust,换个工作就得重新学一套工具。
我这套系统的处理方式是:你写一份 spec,我帮你生成三种引擎的脚本。你选一个跑就行。功能测完之后,再用全站截图做一轮视觉巡检——和压测组成上线前的「双保险」。
一份 spec,三种引擎
先看一个最简单的压测 spec 长什么样。
--- kind: perf_test engine: k6 base_url: http://your-server:5001 stages: - duration: 30s target: 10 - duration: 2m target: 50 - duration: 5m target: 200 - duration: 30s target: 0 thresholds: http_req_duration: ["p(95)<500"] --- ## 登录接口压测 - POST /api/auth/login,参数 {"username":"admin","password":"admin123"} - 预期:200,返回 token ## 商品列表接口 - GET /api/products - 预期:200这份 spec 只有 20 行,但它包含了完整的压测信息:阶梯并发模型(10→50→200)、SLA 阈值(P95<500ms)、测试接口和参数。
kind: perf_test配合engine: k6告诉生成器出 k6 脚本。把engine改成jmeter或locust,同一正文可出不同格式(生成后往往还需按引擎做少量调优)。
这份 spec 之所以能支持三种引擎,是因为 codegen 层做了生成器抽象——perf_test共享解析逻辑,按engine字段分发到 k6 / JMeter / Locust 模板。
# 生成 k6 脚本 ./generate.sh perf_test.md # output/ 下得到 perf_test.js # 生成 JMeter 脚本(需要改 kind 或指定 generator) ./generate_jmeter.sh perf_test.md # 生成 Locust 脚本 ./generate.sh templates/perf_test.md为什么默认引擎选 k6
选择默认引擎时我对比了几种方案:
- JMeter功能最全、插件生态最丰富、支持分布式压测。缺点是不太适合 CI——你要用 GUI 编辑、用命令行跑,JMeter 的 CLI 参数复杂,而且脚本格式是 XML,Git diff 基本没法看。
- Locust用 Python 写脚本,对 Python 工程师友好。但协程模型的并发和真实用户行为之间有一定差距,而且不擅长长时间高并发压测。
- k6的脚本是 JavaScript,但设计上不是给前端工程师写的——它是给测试工程师写压测场景用的。语法简单、支持命令式流程控制、有内置的
check断言和thresholds门禁。而且k6 run可以直接接 CI,输出 JSON 格式的结果给其他工具消费。
所以我最终选 k6 为默认引擎。需要 JMeter 时,我也会生成.jmx文件。
压测的四阶段流水线
压测不是"写个脚本跑一下"就完了。一份有价值的压测报告,需要经过四个阶段。
阶段一:分析。
这个阶段回答"测什么"的问题。识别压测目标、确定接口清单、定义性能指标(TPS、P95、错误率)。AI 在这里做的事情是帮你看 PRD 或者 OpenAPI 文档,标出哪些接口需要关注性能——通常是有数据库操作、有文件上传、有外部依赖的接口。
关于压测环境的说明:本方案默认面向独立压测环境。若需在预发布或生产环境执行,需在 spec 中声明压测标识(如 HTTP 头
X-Load-Test: true),并确保下游服务具备流量隔离与熔断能力。测试环境的硬件规格和数据量级应尽量接近生产,否则压测结论参考价值有限。
阶段二:规划。
定义压测场景。阶梯并发、突发峰值、持续负载?每种场景的组合和参数。AI 在这里做的事情是生成一个压测场景矩阵:
| 场景 | 并发模型 | 持续时间 | 关注指标 |
|---|---|---|---|
| 登录 | 阶梯 10→100 | 3 分钟 | TPS、P95 |
| 商品列表 | 持续 200 | 5 分钟 | 错误率、内存 |
| 下单 | 阶梯 50→200 | 8 分钟 | 数据库连接数 |
| 混合场景 | 随机波动 | 10 分钟 | 全链路指标 |
阶段三:执行。
./generate.sh可以生成 k6/JMeter/Locust 脚本,脚本可在 CI 或本地 CLI 执行。分析、规划、报告解读仍对应 load-testing 下的 AI Skill,不是无人值守全自动。
阶段四:报告。
压测跑完之后,原始数据(k6 的 JSON 输出、JMeter 的聚合报告)需要被解读,转化为可读的报告。这里有一个关键设计:AI 不直接处理原始数据,而是阅读截图和指标,然后输出分析报告。
具体做法是:你把 k6 终端输出或者 JMeter 聚合报告的截图粘贴给 AI,AI 读图识别里面的指标数据,然后按照固定的报告模板输出 Markdown 或 HTML 报告。
这个设计的原因是:原始数据太结构化、太大量了,AI 直接处理容易出错。但截图——人类能看懂的那种——AI 也能看懂,而且处理量小、输出稳定。
需要说明的是:AI 的识图分析存在准确性边界——截图表征、字体过小可能导致数字误读。因此 AI 的分析结论仅作为辅助诊断建议,不作为门禁判定依据;真正的 SLA 阻断仍由 k6/JMeter 原生阈值(thresholds / assertions)负责。
性能瓶颈检查清单
压测报告出来之后,AI 不是只告诉你"P95 超标了",它还会告诉你"可能的问题在哪里"。
我在 load-testing 模块里维护了一份瓶颈检查清单,覆盖了常见的性能问题模式:
| 层次 | 常见瓶颈 | 典型表现 |
|---|---|---|
| 数据库层 | SELECT N+1、缺少索引、连接池耗尽 | TPS 上不去,数据库 CPU 飙升 |
| 应用层 | 同步 I/O 阻塞、大量 JSON 序列化、循环内调外部接口 | P95 持续走高,线程池满载 |
| 网络层 | DNS 解析慢、SSL 握手耗时、负载不均 | 请求延迟集中在网络阶段 |
| 基础设施 | CPU-bound、内存泄漏、磁盘 I/O 瓶颈 | CPU 100% 但 TPS 不动,GC 时间持续增长 |
AI 在分析压测报告时,会结合这些检查清单给出推断和建议。比如"P95 在 200 并发时从 300ms 飙到了 2000ms,同时错误率从 0% 升到了 15%,检查发现数据库连接池配置只有 20,建议调整为 50"。
这种诊断能力当然不如资深 DBA,但它能帮你在发现性能问题后快速定位排查方向,而不是对着监控面板发呆。
全站截图:版本上线前的视觉兜底
上一篇讲了 UI 定位自愈——保证脚本能找到元素、流程能跑通。但「跑得通」不等于「看得对」:样式变形、区块空白、文案错位,定位器+断言经常抓不住。
全站截图模块干的就是这件事。思路很朴素:把每个主要页面截一遍,汇总成 HTML 报告,人扫一眼。screenshot-skills在交付包里标注为需联调——要配好目标站点、登录态和 Playwright 环境后再跑。
范围界定:这里说的"全站"聚焦于核心链路与关键页面——首页、核心流程页、高频访问页,而非严格意义上的全部页面穷举。截图主要用于版本间快速视觉对比,而非像素级回归。登录态过期时,截图模块会先尝试自动续期,续期失败则跳过该页面并记录告警。
三步走完:
- 维护页面清单——URL 列表,标注要不要登录态
- Playwright 批量截图——带 cookie/token,全屏截取
- 生成索引报告——按页面分组,带时间戳和 URL,放进流水线制品
像素级自动对比我刻意没做成硬门禁——时间戳、动画、广告位一变就误报。人工看 HTML 报告,两分钟够扫完主要页面;报告还能归档,出事后回溯"上线前长什么样"。
和压测放一起,就是上线前双保险:压测保速度,截图保视觉。
一个小行动:从一份压测 spec 开始
如果你还没在项目里做性能压测,或者压测脚本还靠手写,不妨试试这个:
把你们线上最核心的一个接口写成一份压测 spec——就像上面的例子那样,20 行够了。然后选你最熟悉的工具,跑一次看看 P95 是多少。
你会发现,把压测从"学工具"变成"写配置",门槛瞬间降了一大截。先跑起来,再优化,比等"准备好了再开始"要现实得多。
为什么自己拼很难
压测工具本身不稀缺。k6、JMeter、Locust 文档都很全,Playwright 截图教程一搜一大把。
难在和前面 spec 体系、后面 CI 门禁是同一条产线。
第一,三引擎共用一份 spec 解析器。kind: perf_test读同一份 Markdown 正文,改engine: k6|jmeter|locust换输出格式。这意味着 stages、thresholds、接口列表的字段约定,要和 API 测试的 spec 格式、codegen 路由表一起设计。
需要诚实地说:虽然 spec 层面统一了场景定义,但不同压测引擎在并发模型、资源调度和指标采集上存在实现差异。生成脚本后仍需针对目标引擎做少量调优,而非完全"零成本切换"。
第二,压测四阶段不是文档好看。分析→规划→执行→报告,每个阶段对应 load-testing 里独立的 Skill 约束:规划产出场景矩阵,报告要求 AI 读截图而不是吞 JSON——这些和瓶颈检查清单、CI 门禁的 P95 维度是咬合的。压测报告里写的「连接池只有 20」,门禁脚本读到的metrics.json里 P95 超标,要能指向同一份结论。
第三,截图不是孤立脚本。页面清单、登录态获取、manifest 索引,和 UI-skills 的登录流程、output 报告目录共用约定。你想在上线流水线里「功能过→截图过→压测过→门禁过」,四处漏一个接口就对不上。
学走这套,瓶颈检查清单、声明式压测 spec、截图巡检降本思路都可以直接拿走。要把它们和用例生成、自愈、缺陷、门禁串成闭环,才是这套技能包真正花时间的地方。
一个小总结
性能压测和全站截图——一个是"压",一个是"看"——共享同一个原则:把重复性的、需要专业工具的操作,变成声明式的、可复用的流程。
- 压测:写 spec + 选 engine,生成脚本后 CLI 执行
- 截图:联调通过后批量截屏 + HTML 索引(非像素级硬门禁)
- 报告:AI 读截图辅助解读;SLA 阻断靠 k6 thresholds 等原生机制
性能压测是「执行」阶段的最后一道硬指标;截图是功能/UI 之后、上线之前的视觉兜底。两者过了,才轮到下一篇的治理层——CI 门禁来把关。
下一篇,最后一篇——缺陷报告、CI 门禁和全链路闭环。怎么让 pytest 失败自动出缺陷草稿?怎么四维度门禁不达标就阻断发布?整条流水线怎么形成质量飞轮?我们最后一篇见。
压测 spec 怎么写、瓶颈从哪几个层排查——这篇的方法论可以独立使用。完整技能包含 HAR 录制定向压测、与门禁阈值联动等工程细节,感兴趣的欢迎交流。