你有没有过这种经历:让AI帮你写一段性能测试脚本,看着它刷刷刷输出了几十行代码,心里一阵暗爽。结果一跑,报错。改完再跑,又报错。来来回回折腾半小时,最后默默关掉窗口,自己手写了一个。
今年AI辅助写代码已经火得不行,但很多测试同行跟我吐槽:“生成的脚本根本没法直接用,修Bug的时间比自己写还长。”这种挫折感,相信不少人都深有体会。直到最近,一位同行在压测一个下单接口时,试着在Prompt里加了一句话。同样的需求描述,生成的Locust脚本复制到PyCharm里,直接跑通,零报错,连压测曲线都稳得一批。
你花半小时改AI脚本,问题出在第一次交流
最近半年,性能测试圈里有个现象越来越明显:大家开始用ChatGPT或Copilot生成Locust、JMeter脚本,但能一次跑通的寥寥无几。表面看是AI能力不行,实际上,是我们跟AI的对话方式,跟当年产品经理给开发提需求一样——“我要一个登录功能”,别的都不说,开发不骂人才怪。
你回想一下,你让AI写脚本时,是不是通常就一句话:“帮我写一个Locust脚本,测试下单接口。”然后AI给了你一堆代码。你复制进去,发现缺少导入、URL硬编码、没有断言、数据参数化没做,甚至连Cookie处理都漏了。
很多人到这里就放弃了,觉得“AI也就那样”。但问题不在AI,在于你给的上下文,比给实习生的还少。本质是,你用自然语言的模糊性,挑战了编程的确定性。
AI写不好脚本,不是它笨,是你没给它上下文
一个合格的性能测试脚本,需要包含哪些信息?目标接口的完整地址、请求方法、Header、Body体结构、参数化数据来源、并发模型、断言规则、运行时长、是否需要模拟用户登录、是否要处理CSRF Token、日志输出格式。
这些东西,在你的脑子里是默认已知的,在你团队的Wiki里是文档化的,但在你发给AI的那句话里,一个都没有。
AI不知道你的环境,不知道你的依赖,不知道你的测试数据在哪,不知道你对成功和失败的定义。它只能靠猜。猜错了,你就得修。核心在于,AI生成的代码质量,不取决于AI本身,取决于你提供的工程约束的密度。
那怎么让这些约束准确地传递给AI?不是写一篇小作文,而是加一句结构化的描述。
一句Prompt,如何把一个“半成品”变成“即用品”
直接看一个增强后的Prompt示例。原始的Prompt是:
“帮我写一个Locust性能测试脚本,压测一个创建订单的API。”
增强后的Prompt,在需求描述末尾,加了一段这样的工程约束:
请严格遵循以下技术规范生成代码:
使用Python 3.10,所有依赖库已安装(locust, requests, faker);被测接口 POST https://api.example.com/orders,Content-Type: application/json,Bearer Token从环境变量TOKEN读取;请求体JSON:userId(随机UUID)、productId(从csv文件./data/products.csv读取并随机选取)、quantity(1-3随机整数);断言:响应状态码201,且响应体中包含字段orderId,并且status为CREATED;Locust并发策略:用户数从环境变量USERS读取,默认100,每秒启动5个用户,运行时长3分钟;脚本需包含on_start方法处理登录获取Token(若TOKEN未设置);添加合理的等待时间(1-3秒随机思考时间),并输出请求失败时的详细响应内容到日志。
把这段话加进去,AI仿佛换了个脑子。生成的代码,import全了,Token处理逻辑有了,数据驱动用CSV读好了,断言精准到字段级别,连日志输出都给你配好了。复制到项目里,只改了环境变量,直接locust -f script.py,压测成功。
为什么有效?因为你把“隐性知识”变成了“显性约束”。下面这张图,能很清楚地解释这个转变:

这就是从“抽奖”到“交付”的跨越。
AI生成代码的可靠性,不取决于你用了多先进的模型,而取决于你给了多明确的工程约束。
两个脚本的命运:通用Prompt vs 工程级Prompt
我们来看一个更具体的案例。压测一个登录接口,传统做法和新做法的差别。
通用Prompt生成的核心片段(节选):
@task
def login(self):
response = self.client.post("/login", json={"username":"test","password":"123"})
# 没有断言,没有参数化,连响应检查都没有
这个脚本跑起来,登录成功还是失败你都不知道,QPS上去全是无效请求。
工程级Prompt生成的核心片段:
import os
import csv
import random
from locust import HttpUser, task, between
import logging
class LoginUser(HttpUser):
wait_time = between(1, 3)
def on_start(self):
# 从CSV读取账号密码
with open('./data/users.csv') as f:
reader = list(csv.DictReader(f))
self.credentials = random.choice(reader)
self.token = None
@task
def login(self):
payload = {"username": self.credentials["username"], "password": self.credentials["password"]}
with self.client.post("/api/login", json=payload, catch_response=True) as resp:
if resp.status_code == 200 and "token" in resp.json():
resp.success()
self.token = resp.json()["token"]
logging.info("Login success")
else:
resp.failure(f"Login failed: {resp.status_code} {resp.text}")
logging.error(f"Failed with payload {payload}")
这段代码,数据驱动、断言、日志、Token存储全有了,零改动直接跑。差距肉眼可见。
这不是魔法,是让你的隐性知识可翻译
这个方法背后,是一个更深刻的工程转变:你需要把你的测试专业知识,从“脑子里的经验”变成“AI可理解的规则”。
以前,测试老手值钱在哪?值钱在他知道这个系统的接口有个隐藏的超时参数要调,知道那个CSV文件的第一行是标题不能删,知道压测前必须先调一个预热接口。这些东西文档里没写,全靠人传人。
现在,有了AI,你的这些隐性知识如果不显性化,AI永远学不会,你每次都得亲自改。但一旦你把它们结构化地写进Prompt,甚至沉淀成团队的“AI测试脚本生成规范”,你的经验就被放大了。一个刚入职的新人,用你维护好的Prompt模板,也能瞬间生成高质量的脚本。
本质是,你从“重复解决同类问题”的执行者,升级成了“定义问题解决范式”的建设者。
下一个阶段,测试工程师的核心竞争力,不是你手写脚本多快,而是你能把多少隐性测试知识,转化成AI能稳定执行的工程约束。
你的团队,有没有一本AI能读懂的“工程字典”
讲完这些,这里不打算给什么标准化的总结。只想让你回头看一眼自己的日常工作。
你每天都在用Postman调接口,用JMeter压测,用Python写自动化脚本。这些工作里,藏着大量只有你或你的小团队知道的“潜规则”:请求头要带特定字段、某个接口有频率限制要先sleep、测试数据要先调用生成接口再消费。
现在我问你一个问题:
你上一次因为环境迁移或新人入职,把这些东西重新口头解释一遍,是什么时候?你有没有想过,把这些“潜规则”整理成一份结构化的工程规范,放进一个Prompt库里,让AI和新人同时能看懂?
如果你开始做这件事了,那你已经不再是那个天天和脚本报错较劲的测试工程师了。你在构建一套质量工程的基础设施。而这份设施,很可能是你下一次跳槽时,最能拉开差距的筹码。
