原文:
https://paul-wanghr.github.io/ 浣花洗剑
K6 测试代码的生命周期
k6的代码有4个生命周期,init code ,vu code,setup,和teardown
// 1. init code 初始化的数据在这里面放
export function setup() {
// 2. setup code
}
export default function(data) {
// 3. vu code
}
export function teardown(data) {
// 4. teardown code
}
K6 的默认报告
k6的报告里面主要包含以下三个点:
- 测试细节(Test details):包括执行模式等
- 进度条(Progress bar):测试的状态和经过了多长时间
- 测试摘要(Test summary):测试结果
Test details
execution: local
output: -
script: script.js
duration: 1m0s, iterations: -
vus: 100, max: 100
execution:local k6的执行模式(local or cloud) output: - 报告的输出模式,默认是stdout。 script: script.js 正在执行的js脚本的名字。 duration: 1m0s :测试的执行的持续时间。 iterations: vu迭代的总次数。 vus: 100 设定的虚拟用户数。 max: 100 测试期间能扩展的最大用户数。
Test summary
报告的这部分分三部分
- Built-in metrics and custom metrics.:内建指标和自定义指标
- Checks and thresholds. : 检查点和阈值判断
- Groups and tags.:分组和标签
Metric Name | TYpe | Description |
---|---|---|
vus | Gauge | 当前运行的vus |
vus_max | Gauge | 最大的vus数 |
iterations | Counter | 测试过程中vus执行js脚本的总次数 |
iteration_duration | Trend | 完成默认函数一次迭代的时间 |
data_received | Counter | 接收的数据量 |
data_sent | Counter | 发送的数据量 |
checks | Rate | 成功的比率 |
HTTP-specific built-in metrics
Metric Name | TYpe | Description |
---|---|---|
http_reqs | Counter | k6产生的总的请求数 |
http_req_blocked | Trend | 等待空闲的TCP连接槽的等待时间 |
http_req_connecting | Trend | 建立到远程主机的TCP连接所花费的时间 |
http_req_tls_handshaking | Trend | 与远程主机握手TLS会话花费的时间 |
http_req_sending | Trend | 发送数据到远程机的时间 |
http_req_waiting | Trend | 等待远程主机所花费的时间 |
http_req_receiving | Trend | 从远程主机接收响应数据所花费的时间 |
http_req_duration | Trend | 请求的总时间= http_req_sending + http_req_waiting + http_req_receiving |
从访问脚本到请求结束的计时
import http from 'k6/http';
export default function() {
var res = http.get('http://httpbin.org');
console.log('Response time was ' + String(res.timings.duration) + ' ms');
}
自定义指标
import http from 'k6/http';
import { Trend } from 'k6/metrics'; //引入指标对象
let myTrend = new Trend('waiting_time'); // 定义指标对象
export default function() {
let r = http.get('https://httpbin.org');
myTrend.add(r.timings.waiting); //加入的指标
}
指标类型
k6有四种指标类型分别是: Counter(计数器), Gauge(计数器), Rate(比率), Trend(趋势)
- Counter:累加
import { Counter } from 'k6/metrics';
let myCounter = new Counter('my_counter');
export default function() {
myCounter.add(1);
myCounter.add(2);
}
累加得三
- Gauge: 最新的值
import { Gauge } from 'k6/metrics'; let demo = new Gauge('Gauge'); export default function() { demo.add(3); demo.add(1); demo.add(2); } 运行一次的话是2,如果运行多次的话到结束的时候可能是3,也可能是1
-
Trend :趋势(平均,最大,百分比)
- rate: 比率-跟踪序列中非0值和true的比值
k6支持的协议
- HTTP/1.1
- HTTP/2
- WebSockets
k6 创建请求
- get请求
import http from 'k6/http';
export default function () {
http.get('http://test.k6.io');
}
- post请求
import http from 'k6/http';
export default function () {
var url = 'http://test.k6.io/login';
var payload = JSON.stringify({
email: 'aaa',
password: 'bbb',
});
var params = {
headers: {
'Content-Type': 'application/json',
},
};
http.post(url, payload, params);
}
k6 支持的http模块的
- batch(): 并行请求,这个是k6和jmter不一样的地方,Jmter的请求只能是顺序执行,这也是基于VUS和基于线程的区别(当然有人也会把不通的请求放到不通的线程组但这样实现可以,但是从逻辑上讲是不通的)
import http from 'k6/http';
import { check } from 'k6';
export default function() {
let responses = http.batch([
['GET', 'https://test.k6.io', null, { tags: { ctype: 'html' } }],
[
'GET',
'https://test.k6.io/style.css',
null,
{ tags: { ctype: 'css' } },
],
[
'GET',
'https://test.k6.io/images/logo.png',
null,
{ tags: { ctype: 'images' } },
],
]);
check(responses[0], {
'main page status was 200': res => res.status === 200,
});
}
针对页面来进行的测试
HTTP请求方法详解
-
batch(method,url,[body],[params]) : 用来做页面同时并发的,所谓的压页面可以用到此方法,前两个参数method和url是必填相,[body]如果没有适用的,使用null。
import http from 'k6/http'; import { check } from 'k6'; export default function() { let responses = http.batch([ ['GET', 'https://test.k6.io', null, { tags: { ctype: 'html' } }], [ 'GET', 'https://test.k6.io/style.css', null, { tags: { ctype: 'css' } }, ], [ 'GET', 'https://test.k6.io/images/logo.png', null, { tags: { ctype: 'images' } }, ], ]); check(responses[0], { 'main page status was 200': res => res.status === 200, }); }
batch的返回值为包含对象的对象。
-
del( url, [body], [params] )
import http from "k6/http"; export default function() { const url = 'https://httpbin.org/delete'; const headers = {'Content-Type': 'application/json'}; const data = { name: 'Bert' }; let res = http.del(url, JSON.stringify(data), {headers: headers}); console.log(JSON.parse(res.body).json.name); };
-
get( url, [params] )
import http from 'k6/http'; export default function() { let res = http.get('https://k6.io'); }
-
options( url, [body], [params] ) http请求配置
-
patch( url, [body], [params] )
import http from "k6/http"; export default function() { const url = 'https://httpbin.org/patch'; const headers = {'Content-Type': 'application/json'}; const data = { name: 'Bert' }; let res = http.patch(url, JSON.stringify(data), {headers: headers}); console.log(JSON.parse(res.body).json.name); };
-
post( url, [body], [params] )
import http from "k6/http"; export default function() { const url = 'https://httpbin.org/post'; let headers = {'Content-Type': 'application/json'}; let data = { name: 'Bert' }; let res = http.post(url, JSON.stringify(data), {headers: headers}); console.log(JSON.parse(res.body).json.name); headers = {'Content-Type': 'application/x-www-form-urlencoded'}; res = http.post(url, data, {headers: headers}); console.log(JSON.parse(res.body).form.name); };
检查点(check)
对于非手动测试执行的用例,我们必须得需要要有一个判断对于业务是否实际真正执行的判断,在自动化测试里面需要,
在自动化性能测试同样需要,在在k6里面叫检查点,在jmeter 里面它叫断言。作用相同。
例子
import { check } from 'k6';
import http from 'k6/http';
export default function () {
let res = http.get('http://test.k6.io/');
check(res, {
'is status 200': (r) => r.status === 200,
});
}