这篇文章详细介绍了 K6 中的 HTTP 请求(http request)功能,解析了常用的性能指标和检查功能。通过 HTTP 请求模拟用户行为,了解性能指标以评估系统响应。文章还深入讲解了如何配置和执行检查,确保性能符合预期标准。无论您是初学者还是经验丰富的性能测试专业人员,这篇教程将为您提供实用知识,助您充分发挥 K6 的性能测试潜力。点击链接,开启高效性能测试之旅!?
使用 K6 进行性能测试的第一步就是定义要测试的 HTTP 请求。
使用?k6 new
?命令创建的 demo 测试脚本中,已经包含了一个简单的 GET 方法 HTTP 请求:
import http from 'k6/http';
import { sleep } from 'k6';
export default function() {
http.get('https://test.k6.io');
sleep(1);
}
这个 POST 请求例子展示一些复杂的场景的应用(带有电子邮件/密码身份验证负载的 POST 请求)
import http from 'k6/http';
export default function () {
const url = 'http://test.k6.io/login';
const payload = JSON.stringify({
email: 'aaa',
password: 'bbb',
});
const params = {
headers: {
'Content-Type': 'application/json',
},
};
http.post(url, payload, params);
}
以上内容参考自?K6 官方文档
K6 提供的 HTTP 模块能处理各种 HTTP 请求和方法。以下是支持的 HTTP 方法列表:
方法 | 作用 |
batch() | 并行发出多个 HTTP 请求(例如浏览器往往会这样做)。 |
del() | 发出 HTTP DELETE 请求。 |
get() | 发出 HTTP GET 请求。 |
head() | 发出 HTTP HEAD 请求。 |
options() | 发出 HTTP OPTIONS 请求。 |
patch() | 发出 HTTP PATCH 请求。 |
post() | 发出 HTTP POST 请求。 |
put() | 发出 HTTP PUT 请求。 |
request() | 发出任何类型的 HTTP 请求。 |
K6 允许为每个 HTTP 请求添加标签,结合标签和分组,可以很方便的在测试结果中更好地组织,分组请求和过滤结果组织分析。
以下为支持的标签列表:
标签 | 作用 |
name | 请求名称。默认为请求的 URL |
method | 请求方法(GET、POST、PUT 等) |
url | 默认为请求的 URL。 |
expected_response | 默认情况下,200 到 399 之间的响应状态为 true。使用 setResponseCallback 更改默认行为。 |
group | 当请求在组内运行时,标记值是组名称。默认为空。 |
scenario | 当请求在场景内运行时,标记值是场景名称。默认为 default。 |
status | 响应状态 |
HTTP 请求使用 tag 和 group 标签的例子会在后续的 demo 中展示。
大家也可以参考官方的例子:https://grafana.com/docs/k6/latest/using-k6/http-requests/
指标用于衡量系统在测试条件下的性能。默认情况下,k6 会自动收集内置指标。除了内置指标,您还可以创建自定义指标。
指标一般分为四大类:
1.?计数器(Counters):对值求和。
2.?计量器(Gauges):跟踪最小、最大和最新的值。
3.?比率(Rates):跟踪非零值发生的频率。
4.?趋势(Trends):计算多个值的统计信息(如均值、模式或百分位数)。
要使测试断言符合需求标准,可以根据性能测试要求的指标条件编写阈值(表达式的具体内容取决于指标类型)。
为了后续进行筛选指标,可以使用标签和分组,这样可以更好地组织测试结果。
测试结果输出文件可以以各种摘要和细粒度格式导出指标,具体信息请参阅结果输出文档。(后面测试结果输出文档会详细介绍这一部分)
每个 k6 测试执行都会发出内置和自定义指标。每个支持的协议也有其特定的指标。
无论测试使用什么协议,k6 始终收集以下指标:
指标名称 | 指标分类 | 指标描述 |
vus | Gauge | 当前活跃虚拟用户数 |
vus_max | Gauge | 最大可能虚拟用户数(VU 资源已预先分配,以避免扩大负载时影响性能) |
iterations 迭代 | Counter | VU 执行 JS 脚本(default 函数)的总次数。 |
iteration_duration | Trend | 完成一次完整迭代的时间,包括在 setup 和 teardown 中花费的时间。要计算特定场景的迭代函数的持续时间,请尝试此解决方法 |
dropped_iterations | Counter | 由于缺少 VU(对于到达率执行程序)或时间不足(基于迭代的执行程序中的 maxDuration 已过期)而未启动的迭代次数。关于删除迭代 |
data_received | Counter | 接收到的数据量。此示例介绍如何跟踪单个 URL 的数据。 |
data_sent | Counter | 发送的数据量。跟踪单个 URL 的数据以跟踪单个 URL 的数据。 |
checks | Rate | 设置的检查成功率。 |
指标分类分别为:计数器(Counter)、计量器(Gauges)、比率(Rates)、趋势(Trends)
HTTP 特定的内置指标是仅在 HTTP 请求期间才会生成和收集的指标。其他类型的请求(例如 WebSocket)不会生成这些指标。
注意:对于所有 http_req_* 指标,时间戳在请求结束时发出。换句话说,时间戳发生在 k6 收到响应正文末尾或请求超时时。
下表列出了 HTTP 特定的内置指标:
指标名称 | 指标分类 | 指标描述 |
http_reqs | Counter | k6 总共生成了多少个 HTTP 请求。 |
http_req_blocked | Trend | 在发起请求之前阻塞(等待空闲 TCP 连接槽)所花费的时间。float 类型 |
http_req_connecting | Trend | 与远程主机建立 TCP 连接所花费的时间。float 类型 |
http_req_tls_handshaking | Trend | 与远程主机握手 TLS 会话所花费的时间 |
http_req_sending | Trend | 向远程主机发送数据所花费的时间。float 类型 |
http_req_waiting | Trend | 等待远程主机响应所花费的时间(也称为“第一个字节的时间”或“TTFB”)。float 类型 |
http_req_receiving | Trend | 从远程主机接收响应数据所花费的时间。float 类型 |
http_req_duration | Trend | 请求的总时间。它等于 http_req_sending + http_req_waiting + http_req_receiving(即远程服务器处理请求和响应所需的时间,没有初始 DNS 查找/连接时间)。float 类型 |
http_req_failed | Rate | 根据 setResponseCallback 的失败请求率。 |
指标分类分别为:计数器(Counter)、计量器(Gauges)、比率(Rates)、趋势(Trends)
K6 内置指标除了标准内置指标和 HTTP 特定的内置指标外,还有其他内置指标:
??Browser metrics 浏览器指标:https://grafana.com/docs/k6/latest/using-k6/metrics/reference/#browser
??Built-in WebSocket metrics 内置 WebSocket 指标:https://grafana.com/docs/k6/latest/using-k6/metrics/reference/#websockets
??Built-in gRPC metrics 内置 gRPC 指标:https://grafana.com/docs/k6/latest/using-k6/metrics/reference/#grpc
除了系统内建的指标之外,您还可以创建自定义指标。例如,您可以计算与业务逻辑相关的指标,或者利用 Response.timings 对象为特定的一组端点创建指标。
每种指标类型都有一个构造函数,用于生成自定义指标。该构造函数会生成一个声明类型的指标对象。每种类型都有一个 add 方法,用于记录指标测量值。
注意:必须在 init 上下文中创建自定义指标。这会限制内存并确保 K6 可以验证所有阈值是否评估了定义的指标。
以下示例演示如何创建等待时间的自定义趋势指标:
项目文件中的 demo_custom_metrics.js 文件已经包含了这个 demo 示例,可以直接运行查看结果。
import?{?Trend?}?from?'k6/metrics';
等待时间趋势指标属于趋势(Trends)指标,所以需要从 k6/metrics 模块引入 Trend 构造函数。
const?myTrend?=?new?Trend('waiting_time');
在 init 上下文中构造一个新的自定义度量 Trend 对象,脚本中的对象为 myTrend,其指标在结果输出中显示为?
waiting_time
。
export default function() {
const res = http.get('https://test.k6.io');
myTrend.add(res.timings.waiting);
}
在脚本中使用 add 方法记录指标测量值,这里使用了?
res.timings.waiting
,即等待时间。
import http from 'k6/http';
import { Trend } from 'k6/metrics';
const myTrend = new Trend('waiting_time');
export default function () {
const res = http.get('https://httpbin.test.k6.io');
myTrend.add(res.timings.waiting);
console.log(myTrend.name); // waiting_time
}
k6?run?demo_custom_metrics.js
运行结果如下:
可以看到,自定义指标?
waiting_time
?已经在结果输出中显示出来了。
更多关于自定义指标的内容,请参考官方文档:https://k6.io/docs/using-k6/metrics/#custom-metrics
这里也可以理解为断言,即对测试结果进行验证。
检查用来检验不同测试中的具体测试条件是否正确相应,和我们常规在做其他类型测试时也会对测试结果进行验证,以确保系统是否以期望的内容作出响应。
例如,一个验证可以确保 POST 请求的响应状态为 201,或者响应体的大小是否符合预期。
检查类似于许多测试框架中称为断言的概念,但是K6 在验证失败并不会中止测试或以失败状态结束。相反,k6 会在测试继续运行时追踪失败验证的比率。
每个检查都创建一个速率指标。要使检查中止或导致测试失败,可以将其与阈值结合使用。
下面会介绍如何使用不同类型的检查,以及如何在测试结果中查看检查结果。
K6 的检查非常适用于与 HTTP 请求相关的响应断言。
示例,以下代码片段来检查 HTTP 响应代码为 200:
import { check } from 'k6';
import http from 'k6/http';
export default function () {
const res = http.get('https://httpbin.test.k6.io');
check(res, {
'HTTP response code is status 200': (r) => r.status === 200,
});
}
运行该脚本,可以看到如下结果:
当脚本包含检查时,摘要报告会显示通过了多少测试检查。
在此示例中,请注意检查“HTTP response code is status 200”在调用时是 100% 成功的。
除了检查 HTTP 响应状态外,还可以检查 HTTP 响应体。
示例,以下代码片段来检查 HTTP 响应体大小为 9591 bytes:
import { check } from 'k6';
import http from 'k6/http';
export default function () {
const res = http.get('https://httpbin.test.k6.io');
check(res, {
'HTTP response body size is 9591 bytes': (r) => r.body.length == 9591,
});
}
运行该脚本,可以看到如下结果:
当脚本包含检查时,摘要报告会显示通过了多少测试检查。
在此示例中,请注意检查“HTTP response body size is 9591 bytes”在调用时是 100% 成功的。
有时候我们在一个测试脚本中需要添加多个检查,那可以直接在单个 check() 语句中添加多个检查,如下面脚本所示:
import { check } from 'k6';
import http from 'k6/http';
export default function () {
const res = http.get('https://httpbin.test.k6.io');
check(res, {
'HTTP response code is status 200': (r) => r.status === 200,
'HTTP response body size is 9591 bytes': (r) => r.body.length == 9591,
});
}
运行该脚本,可以看到如下结果:
在此示例中,两个检查都是正常通过的(调用是 100% 成功的)。
注意:当检查失败时,脚本将继续成功执行,并且不会返回“失败”退出状态。如果您需要根据检查结果使整个测试失败,则必须将检查与阈值结合起来。这在特定环境中特别有用,例如将 k6 集成到 CI 管道中或在安排性能测试时接收警报。
??K6 文档:https://k6.io/docs/
??k6 官方网站:https://k6.io/
??K6 性能测试快速启动项目:https://github.com/Automation-Test-Starter/K6-Performance-Test-starter/
最后:?下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
?行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群:1150305204,里面有各种测试开发资料和技术可以一起交流哦。