前言
前面我已经出了一篇 K6负载测试工具初探的文章,今天我们继续来深入了解 K6
的高级用法。
忽略 https 证书
想信很多同学都遇到了这个问题,当我们的服务协议是 https 时,直接使用示例中的代码会报错缺少证书。但是对于我们测试来说,我们通常会使用忽略证书的方式,requests
是可以在发送请求中增加 verify=False
来实现。那 k6
如何实现呢?
我们可以在测试脚本中增加自定义的配置来开启 https
证书忽略。
import http from 'k6/http';
// k6配置
export const options = {
// 忽略https证书
insecureSkipTLSVerify: true,
};
// setup
// 这就就是你的代码了
setup 和 teardown
从官方文档,我们可以得知 K6
是原生支持 setup
和 teardown
的,我们只需要在测试脚本中定义这两个方法即可。
代码结构:
代码语言:javascript复制import http from 'k6/http';
// 这里就是setup
export function setup() {
const res = http.get('https://httpbin.org/get');
return { data: res.json() };
}
// 这里是你的测试代码
export function teardown(data) {
console.log(JSON.stringify(data));
}
// 这里就是teardown
export default function (data) {
console.log(JSON.stringify(data));
}
断言
对于性能测试,我们也需要对测试结果进行断言,K6
提供了断言方法 check
,你可以使用它自定义断言规则。
// code
export default function () {
const url = 'http://test.test.com:3456/v2.1/server/detail?serverId=serverId';
const params = {
headers: {
'Content-Type': 'application/json'
},
};
let res=http.get(url, params);
// 断言
check(res, {
'response code was 200': (res) => res.status == 200,
});
}
如上,我们可以使用
response
对象中的多个属性进行断言。
自定义失败信息:
代码语言:javascript复制import http from 'k6/http';
import { check, fail } from 'k6';
export default function () {
const res = http.get('http://httpbin.org');
const checkOutput = check(
res,
{
'response code was 200': (res) => res.status == 200,
'body size was 1234 bytes': (res) => res.body.length == 1234,
},
{ myTag: "I'm a tag" }
);
if (!checkOutput) {
fail('unexpected response');
}
}
参数传递(接口统一鉴权)
在测试需要鉴权的接口时,我们通常要在 setup
中获取 token
,然后供后面的测试使用,K6
也原生支持,因为 K6
的测试脚本是使用 JavaScript
写的,所以我们只需要在 setup
中获取到 token
,然后将其 return
出来即可。
这样我们就可以解决接口需要鉴权的问题了。
示例代码:
代码语言:javascript复制import http from 'k6/http';
import { check } from 'k6';
// k6配置
export const options = {
// 忽略https证书
insecureSkipTLSVerify: true,
};
// setup
export function setup() {
console.log('[SETUP]: 开始初始化!');
const url = 'https://test.test.com:5000/v3/auth/tokens';
const payload = JSON.stringify(
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"name": 'admin',
"domain": {
"name": "default"
},
"password": 'pwd@pwd'
}
}
},
"scope": {
"project": {
"domain": {
"id": "default"
},
"name": "admin"
}
}
}
}
);
const params = {
headers: {
'Content-Type': 'application/json',
},
};
let response=http.post(url, payload, params);
const tk = (response.headers)['X-Subject-Token'];
console.log('[SETUP]: 完成初始化!');
console.log(tk)
// 将token返回出去
return tk;
}
// code
// 将前面的tk接收
export default function (tk) {
const url = 'http://test.test.com:3456/v2.1/server/detail?serverId=serverId';
// console.log(tk);
const params = {
headers: {
'Content-Type': 'application/json',
// 在这里传入tk,用于鉴权
'x-auth-token': tk,
'userName': 'admin',
'userId': 'userId',
'projectId': 'projectId'
},
};
// console.log((params.headers)['x-auth-token']);
let res=http.get(url, params);
// console.log(res.body);
// 断言
check(res, {
'response code was 200': (res) => res.status == 200,
});
}
// teardown
export function teardown() {
console.log('[TEARDOWN]: 测试结束!');
}
以上就是完整的对于
https
服务的测试,其包含setup
、teardown
过程,也对测试结果进行了断言。
并发实践
以上的示例是固定的 UV
对单个接口进行的压测,当我们需要模拟实际场景的时候,往往是很多 UV
对多个接口进行访问的。对于这种场景 K6
也提供了 batch
方法,可以实现对多个请求进行并发测试。
第一种写法
// code
export default function () {
// batch 第一种写法
let res=http.batch([
['GET','https://httpbin.org/get',null,{headers:{'Content-Type': 'application/x-www-form-urlencoded'}}],
['POST','https://httpbin.org/post',{hello: 'world!'},{headers:{'Content-Type': 'application/x-www-form-urlencoded'}}]
]);
// 断言1
check(res[0], {
'response code was 200': (res) => res.status == 200,
});
第二种写法
// code
export default function () {
// batch 第二种写法
let req1 = {
method: 'GET',
url: 'https://httpbin.org/get',
};
let req2 = {
method: 'POST',
url: 'https://httpbin.org/post',
body: {hello: 'world!',},
params: {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
},
};
let res = http.batch([req1, req2]);
// 断言2
check(res[0], {
'response code was 200': (res) => res.status == 200,
});
}
实际上,这两种写法的区别就是请求的组装在何处,第一种写法的组装在 batch
内,第二种写法单独组装,然后将请求对象传入 batch
。
测试结果的分析和普通场景同理。
并发权重问题
前面我们已经实现了模拟多个接口的并发,但实际使用中,接口的使用频率是不一样的,所以我们需要能够配置接口的权重。但是我没找到 K6
如何定义接口权重。