本篇博客将讨论 Postman + Newman 的最佳实践,从以下五个方面来展开:
- 初始化
- 测试单个接口
- 测试逻辑功能
- 接口文档
- 接口模拟
目录 Table of Contents
背景
程序写完之后,需要对单个接口和逻辑功能来进行测试,Postman (UI) 和 Newman (CLI) 是很易用且强大的工具。当然它们也拥有提供接口文档和进行接口模拟的功能,虽使用方便但略显粗糙。本博客将着重讨论测试部分,其它功能只做简单介绍,对于概念则不会过多地解释,主要讨论其功能与流程。
初始化
Global
Environment
Dynamic
尽可能地抽取变量,既方便调试时修改数据,又方便自动测试的集成。
测试单个接口
请求内容
- Method:请求方法
- Path:请求路径
- Headers:请求头部
- Params:请求参数
- Body:请求主体
测试内容
Pre-request Script:测试前脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/* 发起请求:用户登录 */
var ip = pm.environment.get("ip");
var port = pm.environment.get("port");
var username = pm.environment.get("username");
var password = pm.environment.get("password");
var body = {
"username": username,
"password": password
};
const postRequest = {
url: "http://" + ip + ":" + port + "/login", // 请求路径
method: 'POST', // 请求方法
header: ['Content-Type:application/json'], // 请求头部
body: { // 请求主体
mode: "raw", // 格式
raw: JSON.stringify(body) // 内容
}
};
pm.sendRequest(postRequest, (err, response) => {
if (err) {
console.log(err);
} else {
console.log(response.json());
}
});
Tests:测试后断言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/* 判断状态码正常:200 */
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
/* 发起请求:用户登录 */
var ip = pm.environment.get("ip");
var port = pm.environment.get("port");
const postRequest = {
url: "http://" + ip + ":" + port + "/logout",
method: 'POST'
};
pm.sendRequest(postRequest, (err, response) => {
if (err) {
console.log(err);
} else {
console.log(response.json());
}
});
/* 设置相关的变量:更新密码 */
var body = JSON.parse(pm.request.body.raw);
pm.environment.set("password", body["password"]);
测试逻辑功能
用例组织
流程跳转:优点是非常灵活,缺点是有点复杂
1
postman.setNextRequest("接口名称");
目录集合:优点是比较直观,缺点是存在冗余
用例设计
创建服务接口
Pre-request Script:
1
2
3
4
5
6
7
8
9
10
11// 生成随机的必填字段
function rand (n, m) {
var num = Math.floor(Math.random() * (m - n + 1) + n)
return num
}
var tcp_port = rand(8001, 8999);
pm.environment.set("tcp_port", tcp_port);
var tcp_service_name = "test_tcp_service_" + rand(1, 100).toString();
pm.environment.set("tcp_service_name", tcp_service_name);Tests:
1
2
3
4
5
6
7
8
9
10
11
12
13// 状态判断
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 错误判断
pm.test("Body not matches string", function () {
pm.expect(pm.response.text()).not.to.include("user not login");
});
// 回写标识
var body = pm.response.json();
pm.environment.set("service_id", body["data"]["info"]["id"]);
查询服务详情接口
- 对 Tests 进行状态判断和错误判断
修改服务接口
Body:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"black_list": "",
"client_ip_flow_limit": 0,
"forbid_list": "",
"ip_list": "127.0.0.1:2333",
"open_auth": 0,
"port": {{tcp_port}},
"round_type": 0,
"service_desc": "updated", // 特殊字串
"service_host_flow_limit": 0,
"service_name": "{{tcp_service_name}}",
"weight_list": "50",
"white_host_name": "",
"white_list": ""
}Tests:
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 状态判断
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 错误判断
pm.test("Body not matches string", function () {
pm.expect(pm.response.text()).not.to.include("user not login");
});
// 子串判断:特殊字串
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("updated");
});
删除服务接口
- 对 Tests 进行状态判断和错误判断
查询服务列表接口
Params:
1
2
3keyword:{{service_name}} // 模糊搜索
//page_index:2
//page_size:2Tests:
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 状态判断
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 错误判断
pm.test("Body not matches string", function () {
pm.expect(pm.response.text()).not.to.include("user not login");
});
// 数量判断:特殊数值
pm.test("Service not found", function () {
pm.expect(pm.response.json().data.total).to.eql(0);
});
运行测试
Postman:界面化操作
Newman:命令行操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# file path: test/postman/*.json
# npm install -g newman
# npm install -g newman-reporter-html or npm install -g newman-reporter-htmlextra
# Initiate a Postman Collection run from a given URL or path
newman run test/postman/giotto-gateway.postman_collection.json \
# Define the number of iterations to run
-n 1 \
# Specify the extent of delay between requests (milliseconds) (default: 0)
--delay-request 0 \
# Specify a URL or path to a Postman Environment
-e test/postman/giotto-gateway_env_local.postman_environment.json \
# Specify a URL or path to a file containing Postman Globals
-g test/postman/giotto-gateway.postman_globals.json \
# Specify the reporters to use for this run (default: ["cli"])
-r htmlextra \
# Export test report as html (default: newman/*.html)
--reporter-html-export giotto-gateway.newman_report.html
接口文档
已支持的功能
- 在线接口文档
- 目录和接口的描述
- 请求示例:根据环境进行填充
- 响应示例:Save response as example
- 生成多种语言的请求代码等
不支持的功能
- 离线接口文档
- 请求参数描述
- 响应参数描述