* Mostafa Moradian(开发者推广大使)著,Ng Wai Foong 译
* 原文网站:k6官方网站
* 原文链接 https://k6.io/blog/zh/load-testing-with-postman-collections/
在本文中,我将解释如何创建Postman集合,以及使用Postman集合来负载测试我们的测试API。整个过程非常简单,您需要导出Postman集合,使用我们的postman-to-k6转换器将其转换为脚本,并使用生成后的k6脚本来负载测试API,如下所示:
# convert postman collection to k6 test
$ postman-to-k6 test-api.json \
-e env.json \
-o k6-script.js
# run load test
$ k6 run \
--vus 100 \
--duration 5m \
k6-script.js
为了演示k6在不同情况下的功能,我们创建了具有各种示例端点的测试API,在test-api.k6.io链接上,这些端点在Postman集合中可用:
公开API
注册和认证API
私有API
本文的用例是测试所有公开和私有API,对于私有API,您可以创建一个用户并提取其令牌,提取后的令牌用于进行其他API调用,调用私有API时,顺序是非常重要的,因为您不能删除不存在的资源。顺便说一下,API中的实例参数(crocodile)也是我们的吉祥物。
为了简化我们的测试,并演示我们的Postman到k6转换器的用法,我创建了一个Postman集合,其中包含了几乎所有测试API的请求,您将很快了解如何使用此Postman集合。
这个集合包含一组集合变量、环境变量、预脚本、测试、授权两种不同的机制,以及Postman沙箱API的用法。
我们为您创建了一个Postman集合转换为k6脚本的工具,它叫postman-to-k6,您可以在发布版本通知中阅读更多关于其功能的信息。
为了将您的Postman集合转换成k6脚本,您应该采取以下步骤:
(可选)步骤1:克隆版本库并跳到第五步骤
我为这篇文章创建了一个存储库,其中包含导出后的Postman集合,转换后的脚本和其他相关的文件。您可以克隆存储库并将test-api.json
和env.json
文件导入到Postman应用程序中。
这个存储库包含了我们负载测试API所需要的一切内容,因此您可以跳到第五步骤,当使用您自己的集合时,您应该遵循所有的步骤,以便能够从Postman集合中转换为k6脚本,并且能够使用它来运行负载测试。
$ git clone https://github.com/k6io/example-postman-collection.git
步骤2:安装Node.js(如果尚未安装)
我强烈建议您使用nvm,这是一个Node.js版本管理器,可以在您的机器上同时启用多个Node.js版本,且能够快速切换到其中任何一个版本。
步骤3:安装postman-to-k6工具
这个postman-to-k6工具是为了帮助您将Postman集合中的请求转换为k6脚本开发的,k6脚本实际上是JavaScript代码。
$ npm install -g postman-to-k6
步骤4:将导出的Postman集合转换为k6脚本
假设您导出的集名为test-api.json
,您可以运行此命令将其转换为k6脚本,输出的env.json
文件包含了从Postman导出的所有环境变量。
$ postman-to-k6 test-api.json -e env.json -o k6-script.js
如果您需要对测试进行更多的微调(就像我们上面所做的那样),比如在您的代码中添加数据或更改环境变量,只需查看postman-to-k6 README的选项
部分。
转换器转换后的脚本应如下所示,我已手动将测试运行的持续时间添加为1分钟,我还添加了虚拟用户(Virtual Users)数,这两个选项让脚本在100个虚拟用户的情况下运行一分钟,这100个用户会尽可能多地发出请求来测试服务器,您会在下一张截图中看到该请求。
import "./libs/shim/core.js";
import "./libs/shim/urijs.js";
import URI from "./libs/urijs.js";
import {
group
} from "k6";
export let options = {
maxRedirects: 4,
duration: "1m",
vus: 100
};
const Request = Symbol.for("request");
postman[Symbol.for("initial")]({
options,
collection: {
BASE_URL: "https://test-api.k6.io/"
},
environment: {
USERNAME: "[email protected]",
PASSWORD: "superCroc2020",
FIRSTNAME: "John",
LASTNAME: "Doe",
EMAIL: "[email protected]",
ACCESS: null,
REFRESH: null,
CROCID: null
}
});
export default function () {
group("Public APIs", function () {
postman[Request]({
name: "List all public crocodiles",
id: "3ddd46c4-1618-4883-82ff-1b1e3a5f1091",
method: "GET",
address: "{{BASE_URL}}/public/crocodiles/"
});
postman[Request]({
name: "Get a single public crocodile",
id: "9625f17a-b739-4f91-af99-fba1d898953b",
method: "GET",
address: "{{BASE_URL}}/public/crocodiles/1/"
});
});
// NOTE: The rest of the requests can be accessed
// from the repository in step 1
});
生成的脚本与普通的k6脚本略有不同,因为它包含了各种抽象来支持Postman中的功能,所以您可以将它们与k6的常规http requests函数混合使用。此外,脚本旁边还有一个libs
目录,其中包含Postman脚本正常运行所需的垫片和库。
步骤5:安装k6
k6支持各种平台,包括Windows、Linux、macOS和Docker,按照安装说明为您的系统安装k6。
注意:您也可以使用choco k6 package在Windows上进行安装。
步骤6:使用生成后的脚本运行k6
将集合转换为k6脚本后,您可以按以下方式运行k6:
$ k6 run k6-script.js
脚本的结果显示在以下命令行界面输出中:
/\ |‾‾| /‾‾/ /‾/
/\ / \ | |_/ / / /
/ \/ \ | | / ‾‾\
/ \ | |‾\ \ | (_) |
/ __________ \ |__| \__\ \___/ .io
execution: local
output: -
script: k6-script.js
duration: 1m0s, iterations: -
vus: 100, max: 100
done [==========================================================] 1m0s / 1m0s
█ Public APIs
█ Registration and authentication
█ Private APIs
data_received..............: 8.8 MB 146 kB/s
data_sent..................: 4.8 MB 80 kB/s
group_duration.............: avg=753.07ms min=239.15ms med=495ms max=4.06s p(90)=1.37s p(95)=1.73s
http_req_blocked...........: avg=12.31ms min=362ns med=1.52µs max=3.47s p(90)=1.83µs p(95)=1.96µs
http_req_connecting........: avg=1.95ms min=0s med=0s max=779.59ms p(90)=0s p(95)=0s
http_req_duration..........: avg=211.11ms min=104.42ms med=183.12ms max=924.43ms p(90)=304.25ms p(95)=404.24ms
http_req_receiving.........: avg=1ms min=41.14µs med=169.38µs max=130.94ms p(90)=328.31µs p(95)=2.22ms
http_req_sending...........: avg=205.91µs min=38.06µs med=163.76µs max=113.06ms p(90)=258.45µs p(95)=302.86µs
http_req_tls_handshaking...: avg=8.69ms min=0s med=0s max=2.43s p(90)=0s p(95)=0s
http_req_waiting...........: avg=209.9ms min=104.05ms med=182.22ms max=891.77ms p(90)=301.29ms p(95)=402.41ms
http_reqs..................: 26363 439.382653/s
iteration_duration.........: avg=2.28s min=1.43s med=2.01s max=6.55s p(90)=2.86s p(95)=3.64s
iterations.................: 2588 43.133267/s
vus........................: 100 min=100 max=100
vus_max....................: 100 min=100 max=100
1. 我们是否应该基于postman-to-k6转换器和Postman集合进行负载测试?
如果您使用转换器作为入门方式,答案是不应该,如果您打算连续转换Postman集合,并且此后无需进行大量手动修改,那么答案是应该。我们建议您使用转换器作为一种简单的方式来加载,然后将您的脚本重写为惯用的 k6 代码,因为我们相信它更易于维护,并且随着时间的推移不太可能降低性能。但是,如果您不断地从Postman集合转换,并按原样运行脚本输出,那么保持原样可能是有意义的。
2. 我可以直接使用转换后的脚本中的所有功能吗?
不可以,由于k6是使用Goja来运行JavaScript,而且它与浏览器和Node.js API是不兼容,因此有一些功能是无法运行使用的。但是您可以通过导入JavaScript模块来解决这个问题,关于兼容库的列表,请参考jslib.k6.io。
3. 对剧本做了哪些调整才能使其正常运行?
首先,我删除了包含pm.sendRequest
的预请求脚本,因为转换器并不支持这个,所以我将jsonData.hasOwnProperty
替换为response.json("selector")
,即用于提取JSON响应信息。
以下是Postman API与k6 API的对比,该表还包含Postman GUI应用程序中的功能,由于k6从一开始就可以编写脚本,您可以选择用JavaScript编写逻辑。此外,Postman是支持使用Javascript来执行各种任务,但Postman的核心在于通过丰富的GUI元素来操作。
功能 | Postman API | k6 API |
---|---|---|
导入外部库 | 一些选定的库 | 一些选定的库加上捆绑库 (非浏览器,非Node.js API) |
发出请求 | ✅ | ✅ |
处理响应 | ✅ | ✅ |
参数化 | ✅ | ✅ |
REST | ✅ | ✅ |
GraphQL | ✅ | ✅ |
小甜饼(Cookies) | ✅ | ✅ |
网络代理 | ✅ | ✅ |
SSL | ✅ | ✅ |
OpenAPI/Swagger | ✅ (直接导入) |
✅ (通过openapi-generator中的k6生成器) |
断言 | ✅ (断言) |
✅ (Checks API) |
组 | ✅ (集合) |
✅ (Group API) |
解析HTML | ✅ (需要外部库) |
✅ (通过内部HTML API) |
上传文件 | ✅ | ✅ |
测试生命周期 | ✅ (需要脚本) |
✅ (内置功能 ) |
根据以上的表,这两个API都支持许多功能,各有千秋,有些功能需要外部库,而有些则是内置功能,这两个API都可以用JavaScript编写脚本,但两者均不支持所有功能,因为两库中使用了各种浏览器和Node.js API。
然而,有些功能只有在k6上才可用,原因在于Postman是专注于API测试或API功能测试服务的,而k6更专注于API负载测试。
功能测试主要是通过API向系统提供输入(作为黑箱),并检查结果,而负载测试基本上与功能测试执行相同的功能,但在系统的输入上有额外的负载。
功能测试在每个端点上提供输入,并根据一组规范对返回的结果进行正确性验证。反过来说,负载测试会在每个端点上提供大量负载,并将汇总所有响应返回的元数据。
元数据将包括发送请求和返回响应所需的时间来衡量性能,以便根据各种指标衡量业绩。例如,您可以测量所有请求的HTTP请求持续时间,并获取其最小值、最大值、平均值、中位数、第90和第95百分位数。
您可以设置某个阈值来断言测试是否通过还是失败。例如,您可以指定希望平均响应时间小于500毫秒,如果平均值低于该数值,则测试将失败,概念和软件测试中的断言是一样的。
由于许多测试涉及来自不同端点的不同结果,如果能对结果进行过滤,就会容易很多,k6支持标签来满足此需求。
在协议实现方面,与Postman相比,WebSocket是k6中可用的功能之一,您可以使用k6中的内置功能对您的WebSocket服务器进行负载测试。
在本文中,我介绍了Postman,postman-to-k6
转换器和我们的k6负载测试工具,您可以使用这些工具将Postman中的API请求转换为k6脚本,以对您的API进行负载测试。我们的postman-to-k6
工具支持许多Postman功能。
我们的最终目标是简化使用我们负载测试工具k6的过程,我们创建了许多集成教程,可以帮助您开始在您的基础设施中进行负载测试。