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 脚本标准结构:
  1. 导入层(Imports):引入 k6 内置模块(http、check、sleep 等)
  2. 配置层(Options):定义虚拟用户数、持续时间、阈值等
  3. 执行层(Default Function):编写实际的 HTTP 请求和业务逻辑
k6 脚本三层结构 第 1 层:导入层(Imports) import http from 'k6/http'; import { check, sleep } from 'k6'; 第 2 层:配置层(Options) export let options = { vus: 10, duration: '30s', thresholds: {...} }; 第 3 层:执行层(Default Function) export default function () { http.get(url); check(res, {...}); sleep(1); } ⚠️ 执行层是唯一 被 k6 循环调用的部分

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:你自定义的检查通过/失败统计
k6 脚本执行流程 1. 解析脚本 2. 初始化 VU 3. 执行迭代 4. 报告 迭代内部循环 http.get() → check() → sleep() → 下一轮 每个 VU 独立循环执行 default function,直到测试结束

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 次迭代验证脚本正确性,再逐步增加并发和持续时间。这能帮你快速定位脚本错误,避免浪费大量测试时间。