4.1 从零开始:第一个 k6 脚本的完整解剖
在编写第一个 k6 脚本之前,你需要理解 k6 脚本的核心——它本质上是 JavaScript (ES6+) 代码,但运行在 k6 内置的 JavaScript 运行时中,而非浏览器。这意味着你不能使用 window、document 等浏览器 API,但可以调用 k6 提供的强大内置模块。
4.1.1 JavaScript 基础回顾:你只需要掌握这些
k6 脚本不需要复杂的 JavaScript 知识。以下是你必须掌握的核心语法,它们足以支撑 90% 的性能测试脚本编写:
| 概念 | 语法示例 | 在 k6 中的用途 |
|---|---|---|
| 变量声明 | let baseUrl = "https://api.example.com"; |
存储配置、URL、参数 |
| 常量声明 | const THINK_TIME = 1; |
定义不变的阈值、常量 |
| 箭头函数 | const add = (a, b) => a + b; |
定义检查函数、回调 |
| 模板字符串 | `/users/${userId}` |
动态拼接请求路径 |
| 对象解构 | const { status, body } = res; |
从响应中提取字段 |
| 数组方法 | data.map(item => item.id) |
处理 CSV/JSON 数据 |
💡 提示: 如果你熟悉 Python 或 Java,JavaScript 的语法非常直观。k6 不支持
import 语句(使用 require),也不支持 DOM 操作。记住这两点,你就能避免 80% 的初学者错误。
4.1.2 k6 脚本的黄金结构:三块基石
每个 k6 脚本都遵循一个固定的三层结构。理解这个结构,你就掌握了编写任何 k6 脚本的框架。
📐 k6 脚本标准结构:
- 导入层(Imports):引入 k6 内置模块(http、check、sleep 等)
- 配置层(Options):定义虚拟用户数、持续时间、阈值等
- 执行层(Default Function):编写实际的 HTTP 请求和业务逻辑
4.1.3 核心武器:http.get 请求
http.get(url, [params]) 是 k6 中最常用的方法。它发送一个 HTTP GET 请求并返回一个 Response 对象。这个对象包含了你在性能测试中需要的一切:
| Response 属性 | 类型 | 说明 | 典型用途 |
|---|---|---|---|
status |
Number | HTTP 状态码 | 检查是否 200/201/404 |
body |
String | 响应体文本 | 解析 JSON、提取数据 |
headers |
Object | 响应头键值对 | 检查 Content-Type |
timings |
Object | 请求耗时详情 | 分析性能瓶颈 |
json() |
Function | 将 body 解析为 JSON | 快速提取嵌套字段 |
⚠️ 常见陷阱: 不要忘记
sleep(1)!在性能测试中,如果不添加思考时间(think time),你的虚拟用户会以最大速率发送请求,这通常不符合真实用户行为,会导致服务器被压垮,测试结果失真。通常建议在每次迭代末尾添加 sleep(1) 到 sleep(3) 秒。
4.1.4 完整脚本实战:导出与运行
现在,让我们将以上所有知识整合成一个完整的、可运行的 k6 脚本。这个脚本将模拟 10 个虚拟用户在 30 秒内持续访问一个 API 端点。
// 第 1 层:导入层
import http from 'k6/http';
import { check, sleep } from 'k6';
// 第 2 层:配置层
export let options = {
vus: 10, // 10 个虚拟用户
duration: '30s', // 持续 30 秒
thresholds: {
http_req_duration: ['p(95)<500'], // 95% 的请求响应时间 < 500ms
http_req_failed: ['rate<0.01'], // 失败率 < 1%
},
};
// 第 3 层:执行层
export default function () {
// 发送 GET 请求
let res = http.get('https://test-api.k6.io/public/crocodiles/');
// 检查响应
check(res, {
'状态码是 200': (r) => r.status === 200,
'响应时间 < 300ms': (r) => r.timings.duration < 300,
'返回数据非空': (r) => r.body.length > 0,
});
// 模拟用户思考时间
sleep(1);
}
4.1.5 运行脚本:从命令行到报告
将上述代码保存为 first-test.js,然后在终端中运行以下命令:
# 运行脚本(输出到终端)
k6 run first-test.js
# 运行脚本(输出 HTML 报告)
k6 run --out html=report.html first-test.js
# 运行脚本(输出 JSON 日志)
k6 run --out json=result.json first-test.js
📊 运行结果解读:
- http_req_duration:平均响应时间、P95、P99 等关键指标
- http_req_failed:请求失败率,用于判断系统稳定性
- vus:实际运行的虚拟用户数
- iterations:总迭代次数,反映吞吐量
- checks:你自定义的检查通过/失败统计
4.1.6 脚本调试技巧:快速验证你的第一个脚本
在运行大规模测试之前,先用 调试模式 验证脚本的正确性:
- 使用
--iterations 1:只执行一次迭代,快速检查语法和逻辑 - 使用
--vus 1:单用户模式,排除并发问题 - 打印调试信息:使用
console.log()输出变量值(仅在调试时使用,生产环境移除) - 检查响应体:使用
console.log(res.body)查看 API 返回的实际数据
# 调试命令示例
k6 run --vus 1 --iterations 1 first-test.js
💡 最佳实践: 在编写复杂脚本时,始终遵循“先调试,后压测”的原则。先用 1 个 VU 和 1 次迭代验证脚本正确性,再逐步增加并发和持续时间。这能帮你快速定位脚本错误,避免浪费大量测试时间。