K6 是一款基于 Go 语言开发的开源性能测试工具,支持多种操作系统,安装过程非常简单:
https://github.com/grafana/k6/releases下载安装包,安装完成后,在命令行输入以下命令验证:
k6 version如果正确输出版本号,则说明安装成功。
K6 的测试脚本基于 JavaScript/TypeScript 编写,主要包含以下核心概念:
K6 自动收集的关键指标:
// 主要性能指标示例
http_req_duration // HTTP请求响应时间
http_req_failed // HTTP请求失败率
iteration_duration // 单次迭代执行时间
vus // 活跃虚拟用户数
vus_max // 最大虚拟用户数用于定义测试通过 / 失败的标准:
export const options = {
thresholds: {
// 响应时间相关阈值
'http_req_duration': ['avg < 500', 'p(95) < 1000'],
// 错误率阈值
'http_req_failed': ['rate < 0.01'],
// 自定义标签阈值
'http_req_duration{group:::登录接口}': ['avg < 800']
}
};用于验证单个请求的结果:
import { check } from'k6';
import http from'k6/http';
exportdefaultfunction() {
const res = http.get('https://test-api.k6.io');
// 添加检查点
check(res, {
'状态码为200': (r) => r.status === 200,
'响应时间小于500ms': (r) => r.timings.duration < 500,
'返回内容包含特定文本': (r) => r.body.includes('Welcome to the k6.io test API')
});
}用于逻辑组织测试用例:
import { group } from'k6';
import http from'k6/http';
exportdefaultfunction() {
// 用户管理测试套件
group('用户管理', function() {
// 登录流程子套件
group('登录流程', function() {
http.get('https://test-api.k6.io/login');
});
// 注册流程子套件
group('注册流程', function() {
http.post('https://test-api.k6.io/register');
});
});
}用于控制虚拟用户的加载模式:
export const options = {
scenarios: {
// 渐进式加载场景
渐进式压力测试: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '10s', target: 10 }, // 10秒内增加到10个VU
{ duration: '20s', target: 10 }, // 保持10个VU运行20秒
{ duration: '5s', target: 0 }, // 5秒内逐步停止
],
},
// 固定并发场景
固定并发测试: {
executor: 'constant-vus',
vus: 50,
duration: '30s',
}
}
};以下是一个完整的接口测试脚本示例,包含并发控制、多级分组和结果验证:
import http from'k6/http';
import { check, group, sleep } from'k6';
// 配置测试参数
exportconst options = {
// 控制并发用户数和持续时间
scenarios: {
api_test: {
executor: 'constant-vus',
vus: 10, // 10个并发用户
duration: '30s', // 持续30秒
}
},
// 设置性能阈值
thresholds: {
// 验证指定编号用例的响应时间
'http_req_duration{case_id:1}': ['avg < 6000'], // 平均响应时间小于6秒
// 验证分组中请求的响应时间
'http_req_duration{group:::用户管理}': ['p(90) < 6000'], // 90%请求小于6秒
// 验证分组整体执行时间
'group_duration{group:::用户管理}': ['avg < 6000'], // 平均执行时间小于6秒
},
};
// 自定义断言函数,支持测试用例编号和名称
functionassert(caseId, caseName, checkpoint, data, validator) {
const name = `${caseId} - ${caseName}`;
const tags = { case_id: caseId, case_name: caseName, checkpoint: checkpoint };
returncheck(data, { [name]: validator }, tags);
}
exportdefaultfunction() {
// 模拟测试套件 - 用户管理
group('用户管理', function() {
// 登录接口测试
group('登录流程', function() {
// 测试用例1: 正常登录
let resp = http.post('https://api.example.com/login', {
username: 'testuser',
password: 'testpass'
}, {
tags: { case_id: '1' } // 标记用例编号
});
// 验证登录接口
assert(1, '正常登录', '状态码200', resp, (r) => r.status === 200);
assert(1, '正常登录', '包含token', resp, (r) => r.json().token !== undefined);
// 模拟登录后操作
const token = resp.json().token;
sleep(1);
// 测试用例2: 获取用户信息
resp = http.get('https://api.example.com/user/info', {
headers: {
'Authorization': `Bearer ${token}`
},
tags: { case_id: '2' }
});
assert(2, '获取用户信息', '状态码200', resp, (r) => r.status === 200);
assert(2, '获取用户信息', '包含用户名', resp, (r) => r.json().username === 'testuser');
});
// 注册接口测试
group('注册流程', function() {
// 测试用例3: 正常注册
const randomEmail = `user${Math.floor(Math.random() * 10000)}@example.com`;
const resp = http.post('https://api.example.com/register', {
email: randomEmail,
username: `user${Math.floor(Math.random() * 10000)}`,
password: 'testpass123'
}, {
tags: { case_id: '3' }
});
assert(3, '正常注册', '状态码201', resp, (r) => r.status === 201);
assert(3, '正常注册', '包含用户ID', resp, (r) => r.json().id !== undefined);
});
});
// 模拟测试套件 - 订单管理
group('订单管理', function() {
// 测试用例4: 创建订单
const resp = http.post('https://api.example.com/orders', {
product_id: 123,
quantity: 2,
address: '北京市朝阳区'
}, {
tags: { case_id: '4' }
});
assert(4, '创建订单', '状态码201', resp, (r) => r.status === 201);
assert(4, '创建订单', '订单号有效', resp, (r) => r.json().order_number !== undefined);
});
}
// 输出JSON格式的测试结果
exportfunctionhandleSummary(data) {
return {
'results/summary.json': JSON.stringify(data, null, 2),
'stdout': JSON.stringify(data, null, 2) // 也输出到控制台
};
}执行测试后,K6 会输出详细的测试结果,主要包含以下关键部分:
running (0m30.0s), 0/10 VUs, 300 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 30schecks.........................: 100.00% ✓ 600 ✗ 0 http_req_duration..............: avg=420.32ms min=120.45ms med=389.22ms max=1250.67ms p(90)=750.34ms p(95)=890.12ms
group_duration.................: avg=1.2s min=0.8s med=1.1s max=2.5s p(90)=1.8s p(95)=2.0s
http_req_failed................: 0.00% ✓ 0 ✗ 300✓ { case_id:1 }................: avg=350.23ms min=120.45ms max=580.12ms p(90)=520.34ms
✓ { group:::用户管理 }..........: p(90)=590.45ms
✓ { group:::用户管理 }..........: avg=1100.23ms#性能测试 #k6