k6 是最近发现比较有趣的压测工具它是通过 JS 创建测试脚本的这方面跟 Gatling 类似不过 Gatling 使用 Scala 创建测试脚本。 k6 底层的执行引擎是使用 Go 开发的内嵌了 JavaScript 运行时所以可以使用 JS 创建测试脚本而且使用 JS 作为测试脚本语言也是明智的选择因为 JS 真的非常的流行更加具有普适性。k6 压测工具比 JMeter 压测工具更轻量化占用更少的资源性能更好些。安装由于笔者使用 Win 11 操作系统而且 Win 11 操作系统内置了 winget 安装工具所以笔者直接使用 winget 安装 k6winget install k6其他的安装方式可以参考安装文档。k6 的使用k6 的 Hello Worldk6 有一个测试页面但是国内访问比较慢若对测试脚本编写有疑惑的可以参考一下测试页面的案例。学习编程从 Hello World 开始创建一个测试脚本hello-world.jsimport http from k6/http; import { sleep } from k6; export default function () { http.get(https://www.baidu.com/); // sleep() 函数作为多个串联请求的思考时间 sleep(1); }default function 就相当于 Java 的 Main 方法是程序的入口。默认参数运行# 默认参数是每个 URL 1 个虚拟用户访问一次 k6 run hello-world.js模拟 10 个虚拟用户(VU)连续压测 30 秒k6 run --vus 10 --duration 30s hello-world.js也可以把这些参数写到脚本里(效果和上面命令行一样)import http from k6/http; import { sleep } from k6; export const options { vus: 10, duration: 30s, }; export default function () { http.get(https://www.baidu.com/); sleep(1); }k6 压测结果数据解读下面的测试结果是运行上述hello-world.js测试脚本所得的测试结果由多个数据汇总而成下面解读一下各个数据表示什么意思。scenarios简述测试脚本运行的情况说明有多少个测试案例、最大的虚拟用户数最大的运行持续时间。data_received接收到的数据量大小data_sent发送的数据量大小http_req_blocked在发起请求之前被阻塞的时间http_req_connecting建立到远程主机的 TCP 连接所花费的时间http_req_duration请求的总时间。它等于 http_req_sending http_req_waiting http_req_receiving重要指标http_req_failed失败请求率http_req_receiving从远程主机接收响应数据所花费的时间而没有初始DNS查找/连接时间http_req_sending将数据发送到远程主机所花费的时间http_req_tls_handshaking与远程主机握手建立TLS会话所花费的时间http_req_waiting等待远程主机响应所花费的时间http_reqs总请求数量TPSiteration_duration完成默认/主函数的一次完整迭代所花费的时间iterations脚本中的函数被执行的次数vus当前活动的虚拟用户数vus_max虚拟用户的最大数量checkschecks 项的成功率HTTP RequestsGet 请求Get 请求的语法是get(url,[params])import http from k6/http; export let options { vus: 100, // 指定要同时运行的虚拟用户数量 duration: 10s, // 指定测试运行的总持续时间 }; // default 默认函数 export default function () { // 通过 params 设置标头 let params { headers: { Content-Type: application/json } }; var reshttp.get(https://test.k6.io,params) }Post 请求Post 请求的语法是post(url,[body],[params]import http from k6/http; // 加载本地的文件数据通过文件数据可以构建动态参数请求了download the data file here: https://test.k6.io/static/examples/users.json // 加载的数据不能直接传输给后端传输给后端需要使用 JSON.stringify() 转换一下 // 若是直接传输给后端就不需要转换成 JSON也就是省略 JSON.parse() 这部调用 const loginData JSON.parse(open(./users.json)); export default function () { const url http://test.k6.io/login; // Using a JSON string as body const payload JSON.stringify({ email: aaa, password: bbb, }); const params { headers: { Content-Type: application/json, }, }; http.post(url, payload, params); }通用 Request通用 Request 的语法是request(method,url,[body],[params])import http from k6/http; const url https://httpbin.test.k6.io/post; export default function () { const data { name: Bert }; // Using a JSON string as body let res http.request(POST, url, JSON.stringify(data), { headers: { Content-Type: application/json }, }); console.log(res.json().json.name); // Bert // Using an object as body, the headers will automatically include // Content-Type: application/x-www-form-urlencoded. res http.request(POST, url, data); console.log(res.json().form.name); // Bert }关于 HTTP Requests 更多的请求处理方式请参考HTTP Requests 文档响应结果断言一个请求是否正确需要根据返回结果进行判断判断请求返回结果一般是使用断言的。k6 必然也是提供响应结果断言检查的但断言失败不会导致测试中止或以失败状态结束。相反k6 在测试继续运行时跟踪失败检查的比率。响应结果结构体可以参考文档Response。检查 HTTP 响应代码检查非常适合编码与 HTTP 请求和响应相关的断言。例如此代码段确保 HTTP 响应代码为 200import { check } from k6; import http from k6/http; export default function () { const res http.get(http://test.k6.io/); check(res, { is status 200: (r) r.status 200, }); }当脚本包含检查时摘要报告会显示通过了多少测试检查k6 run script.js ... ✓ is status 200 ... checks.........................: 100.00% ✓ 1 ✗ 0 data_received..................: 11 kB 12 kB/s在此示例中请注意检查“状态为 200”的调用成功率为 100%。检查响应正文中的文本有时即使是 HTTP 200 响应也包含错误消息。在这些情况下考虑添加一个检查来验证响应主体如下所示import { check } from k6; import http from k6/http; export default function () { const res http.get(http://test.k6.io/); check(res, { verify homepage text: (r) r.body.includes(Collection of simple web-pages suitable for load testing), }); }若请求结果以 JSON 格式返回我们可以校验 JSON 对象的import { check } from k6; import http from k6/http; export default function () { const res http.get(http://test.k6.io/); /* { status:1, code:SYS_OK, message:请求成功, data:[] } 例如请求返回值是上面的 JSON 对象所以需要判断 status 字段才能判断请求是否成功。 */ // res.json([select]) 可以将响应结果转换为 JSON 对象或 JSON 数组 // 通过可选参数 select 获取某个字段值的 check(res, { status was 200: (r) r.status 200, business status was 0: (r) r.json(status) 0 }); }res.json([select])函数的更多内容可以参考Response.json( [selector] )。检查响应主体大小要验证响应主体的大小您可以使用如下检查import { check } from k6; import http from k6/http; export default function () { const res http.get(http://test.k6.io/); check(res, { body size is 11,105 bytes: (r) r.body.length 11105, }); }添加多项检查您还可以在单个check()语句中添加多个检查import { check } from k6; import http from k6/http; export default function () { const res http.get(http://test.k6.io/); check(res, { is status 200: (r) r.status 200, body size is 11,105 bytes: (r) r.body.length 11105, }); }执行此测试时输出将如下所示k6 run checks.js ... ✓ is status 200 ✓ body size is 11,105 bytes ... checks.........................: 100.00% ✓ 2 ✗ 0 data_received..................: 11 kB 20 kB/sOption 选项虚拟用户Vus指定要同时运行的虚拟用户数量必须是一个整数和 duration 搭配使用。默认值1export let options { vus: 10, duration: 10s, };k6 run -u 10 test.js k6 run --vus 10 test.js持续时间Duration一个字符串 指定测试运行的总持续时间与 vus 选项一起使用。默认值nullexport let options { vus: 10, duration: 10s, };k6 run -u 10 --d 20s test.js k6 run --vus 10 --duration 20s test.js模拟多阶段RPS每秒发出的最大请求数 默认值0k6 压测默认是并发模式配置了 RPS 应该调整为吞吐量模式限定压测的 RPS。不推荐使用这个选项因为它有可能不正确例如在云端或分布式执行中此选项独立影响每个 k6 实例。也就是说它不像 VU 那样被分片。我们强烈建议到达率执行器模拟恒定 RPS而不是这个选项。export let options { rps: 500, };模拟多测试阶段import http from k6/http; import { check, sleep } from k6; export const options { stages: [ { duration: 30s, target: 20 }, { duration: 1m30s, target: 10 }, { duration: 20s, target: 0 }, ], }; export default function () { const res http.get(https://www.baidu.com/); check(res, { status was 200: (r) r.status 200 }); sleep(1); }前 30 秒用户从 0 增涨到 20。然后接下来的 1 分 30 秒持续模拟 10 个用户。然后用 20 秒的时间把并发用户数从 10 减少到 0。趋势汇总统计k6 默认的趋势汇总统计格式是avg,min,med,max,p(90),p(95)我们可以自定义趋势汇总统计例如我们需要关注p(99)这个指标那么我们可以自定义summaryTrendStats的值# 添加 p(99) 指标 export const options { summaryTrendStats: [avg, min, med, max, p(90),p(95), p(99)] }日志输出输出到控制台import http from k6/http; export let options { vus: 10, duration: 2s, }; export default function () { let res http.get(http://www.baidu.com); console.log(log) console.info(info); console.error(err); console.debug(debug) console.warn(warn) }输出到文件输出到文件的同时控制台不再输出k6 run test.js --console-outputtest.logk6 脚本的调试在使用 k6 的时候遇到了一个问题请求后端接口的时候报 JSON 相关的错误突然想到该如何调试 K6 的脚本呢经过查询发现 k6 的脚本不能很好的支持调试因为 k6 的底层是基于 Go 而不是 Node.js 的k6 只是使用了 Javascript 脚本作为测试内容的调试器而已。所以调试 k6 脚本比较有效的 方式是实用console.log()函数了。若是想了解 HTTP API 接口的请求情况可以使用--http-debug参数更多详细内容参考HTTP debuggingk6 测试结果的可视化Web dashboard通过 web dashboard 我们可以在本地浏览器 实时查看接口测试情况。Web Dashboard 是 k6 的内置功能。你可以在运行测试脚本时通过设置K6_WEB_DASHBOARD环境变量 来启用它true例如k6 --out web-dashboard run script.js /\ |‾‾| /‾‾/ /‾‾/ /\ / \ | |/ / / / / / \ | ( / ‾‾\ / \ | |\ \ | (‾) | / __________ \ |__| __\ _____/ .io execution: local script: ../extensions/xk6-dashboard/script.js web dashboard: http://127.0.0.1:5665 output: -默认情况下Web Dashboard 在 localhost 端口上可用。您可以使用仪表板选项5665更改主机和端口。通过 k6 Cloud 进行可化我们可以将本地的测试结果输出到 k6 Cloud借助 k6 Cloud 生成优美的测试结果页面。要使用 k6 Cloud 需要先注册app.k6.io推荐直接用 Github 账号登录研发人员肯定有 Github 账号吧。使用 Github 登录的时候一直出错所以笔者使用 Google 账号登录了。登录成功后通过自己的账户获取 API Token复制API token然后在命令行运行k6 login cloud --token YOUR_K6_CLOUD_API_TOKEN这样你的客户端 k6 程序也知道了如何访问你的云端。将运行测试脚本之后的结果上传到云端生成更直观和更可读的测试结果通过添加--out cloud或-o cloud参数即可将测试结果上传到云端k6 run --out cloud hello-world.js 或简写 k6 run -o cloud hello-world.js因为之前通过 API token我们已经让本地程序绑定了云端。现在测试数据会实时发送到云端测试结果如下对于一次压力测试来说其实最关心的就是红框里的这几个数据了。还可以生成测试报告并且生成测试结果的 PDF 文件最后下方这份完整的软件测试 视频教程已经整理上传完成需要的朋友们可以自行领取【保证100%免费】软件测试面试文档我们学习必然是为了找到高薪的工作下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料并且有字节大佬给出了权威的解答刷完这一套面试资料相信大家都能找到满意的工作。