K6工具
安装
Win 11 操作系统内置了 winget 安装工具,所以笔者直接使用 winget 安装 k6:
1
winget install k6
其他的安装方式可以参考安装文档。
k6 的使
k6 的 Hello World
创建一个测试脚本hello-world.js:
1
2
3
4
5
6
7
8
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
http.get('https://www.baidu.com/');
// sleep() 函数作为多个串联请求的思考时间
sleep(1);
}
默认参数运行:
arduino 体验AI代码助手 代码解读复制代码# 默认参数是每个 URL 1 个虚拟用户访问一次
k6 run hello-world.js
模拟 10 个虚拟用户(VU),连续压测 30 秒:
1
k6 run --vus 10 --duration 30s hello-world.js
也可以把这些参数写到脚本里(效果和上面命令行一样):
1
2
3
4
5
6
7
8
9
10
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:总请求数量TPS
- iteration_duration:完成默认/主函数的一次完整迭代所花费的时间
- iterations:脚本中的函数被执行的次数
- vus:当前活动的虚拟用户数
- vus_max:虚拟用户的最大数量
- checks:checks 项的成功率
HTTP Requests
Get 请求
Get 请求的语法是get(url,[params])
1
2
3
4
5
6
7
8
9
10
11
12
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 res=http.get("https://test.k6.io",params)
}
Post 请求
Post 请求的语法是post(url,[body],[params]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 响应代码为 200:
1
2
3
4
5
6
7
8
9
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,
});
}
当脚本包含检查时,摘要报告会显示通过了多少测试检查:
1
2
3
4
5
6
7
8
k6 run script.js
...
✓ is status 200
...
checks.........................: 100.00% ✓ 1 ✗ 0
data_received..................: 11 kB 12 kB/s
在此示例中,请注意检查“状态为 200”的调用成功率为 100%。
检查响应正文中的文本
有时,即使是 HTTP 200 响应也包含错误消息。在这些情况下,考虑添加一个检查来验证响应主体,如下所示:
1
2
3
4
5
6
7
8
9
10
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 对象的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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] )。
检查响应主体大小
要验证响应主体的大小,您可以使用如下检查:
1
2
3
4
5
6
7
8
9
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()语句中添加多个检查:
1
2
3
4
5
6
7
8
9
10
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,
});
}
执行此测试时,输出将如下所示:
1
2
3
4
5
6
7
8
9
k6 run checks.js
...
✓ is status 200
✓ body size is 11,105 bytes
...
checks.........................: 100.00% ✓ 2 ✗ 0
data_received..................: 11 kB 20 kB/s
Option 选项
虚拟用户
Vus:指定要同时运行的虚拟用户数量,必须是一个整数,和 duration 搭配使用。默认值:1
1
2
3
4
5
6
export let options = {
vus: 10,
duration: '10s',
};
arduino 体验AI代码助手 代码解读复制代码k6 run -u 10 test.js
k6 run --vus 10 test.js
持续时间
Duration:一个字符串,指定测试运行的总持续时间,与 vus 选项一起使用。默认值:null
1
2
3
4
5
6
export let options = {
vus: 10,
duration: '10s',
};
css 体验AI代码助手 代码解读复制代码k6 run -u 10 --d 20s test.js
k6 run --vus 10 --duration 20s test.js
模拟多阶段
RPS:每秒发出的最大请求数, 默认值:0;k6 压测默认是并发模式,配置了 RPS 应该调整为吞吐量模式,限定压测的 RPS。
不推荐使用这个选项,因为它有可能不正确;例如,在云端或分布式执行中,此选项独立影响每个 k6 实例。也就是说,它不像 VU 那样被分片。我们强烈建议到达率执行器模拟恒定 RPS,而不是这个选项。
1
2
3
ini 体验AI代码助手 代码解读复制代码export let options = {
rps: 500,
};
模拟多测试阶段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)']
}
日志输出
输出到控制台:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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')
}
输出到文件,输出到文件的同时控制台不再输出:
1
run test.js --console-output=test.log
k6 测试结果的可视化
通过 http://127.0.0.1:5665 我们可以在本地浏览器实时查看接口测试情况。


