作为邮递员的工程师,我和许多使用邮递员测试他们的API的人交谈。多年来,我收集了10个技巧和技巧,以简化和自动化API测试任务。
提示#1:写测试
API测试的第一步就是要做到这一点。没有好的测试,就不可能对您的API的行为,一致性或向后兼容性充满信心。随着您的代码库随着时间的推移而变化,测试将通过发现突破性更改来节省时间和沮丧。
在Postman中编写测试很容易,
并使用JavaScript语法。测试简单的东西,如HTTP状态代码,响应时间和标题都可以在一行代码中完成,如下所示:
提示#2:不要混合测试和文档
许多人使用
Postman Collections
来记录他们的API,作为可以
在团队成员之间
轻松
共享
的示例请求的集合,或作为客户的
公共API文档
。对于这两种用例,您的收藏包含每个API端点的详细说明,通用API工作流程的演练,身份验证要求,可能的错误响应列表等都是有意义的。
另一方面,您的API测试完全独立于目的。
首先,观众是不同的。而API文档是API的
消费者
,测试是针对API 的
作者
。
其次,内容是不同的。一个坚实的测试套件将包括许多边缘案例,有意的错误输入(测试错误处理),并且可能会显示敏感信息,所有这些信息对您的API消费者来说都是无关紧要的或令人困惑的。
最后,作者可能会有所不同。文档(特别是公共文档)可能由您的营销团队或技术作者撰写,而测试则由构建API的开发人员或负责验证API的测试人员编写。
由于所有这些原因,我强烈建议您将API测试与您的API文档
分开收集
。是的,这意味着你必须管理两个不同的集合,但是根据我的经验,这些集合的内容最终会有很大的不同,它们之间几乎没有重叠或重复。而且,正如本文后面将会看到的那样,将测试分开在自己的集合中,开启了一些强大的自动化可能性。
>奖金提示:
您通常用于您的API文档的描述字段可以重新调整为测试描述。这是记录测试的好方法,所以开发人员和测试人员知道正在测试的内容,预期的输出结果等等。
提示#3:将测试组织到文件夹中
资源
测试套房
第二级文件夹将是每种资源的测试套件,例如“
开始新订单
”,“
编辑现有订单
”,“
取消订单
”等。
对于仅需要单个API调用的简单测试,就不需要第三级文件夹。您可以直接在测试套件文件夹下创建请求。一定要给你的请求有意义的名字来区分它们,并描述他们正在测试什么。例如,“
编辑现有订单
”测试套件文件夹可能包含“
添加产品
”,“
删除产品
”,“
更改送货地址
”等请求。
工作流程
第三级文件夹用于跨越多个API调用的更复杂的测试。例如,您的API可能有一个结帐流程,涉及单独的呼叫,以从购物车创建订单,输入送货地址,选择出货方式并提交付款信息。在这种情况下,您将创建一个名为“
Checkout
” 的“工作流”文件夹,其中包含三个请求。
提示#4:JSON模式验证
当然,您可能不想在测试脚本中对JSON Schema进行硬编码,特别是因为您可能需要为集合中的许多请求使用相同的模式。因此,您可以将模式作为JSON字符串存储在
Postman环境变量中
。那么你可以简单地在测试脚本中使用变量,如下所示:
提示#5:重用代码
大多数API具有适用于大多数(或全部)端点的一些常见规则。应始终设置某些HTTP标头,或响应主体应始终为特定格式,或者响应时间必须始终在可接受的限度内。而不是为每个请求重写这些测试,您可以在收集的第一个请求中写入一次,然后在每个请求之后重新使用它们。
集合中的首要要求:
集合中的其他要求:
提示6:邮递员BDD
Postman的默认测试语法非常简单易学,但很多人喜欢流行的JavaScript测试库(如
摩卡
和
柴)
的语法。我恰巧是那些人之一,这就是为什么我创建了
邮递员BDD
。Postman BDD允许您使用
摩卡的BDD语法
编写Postman测试。它利用上一个提示的“可重用代码”技巧来加载
Chai
和
Chai-HTTP
,这意味着您可以这样编写测试:
提示#7:使用邮递员收集赛跑者自动进行测试
提示#8:用Newman自动进行测试
邮递员收集跑步者是运行所有测试并查看结果的好方法,但仍需要您手动启动运行。如果您希望将Postman测试作为Continuous Integration或Continuous Delivery管道的一部分运行,则需要使用
Newman CLI
。
Newman可以很容易地集成到
Jenkins
,
AppVeyor
,
Bamboo
,
CodeShip
,
Travis CI
,
Circle CI
或任何其他代码部署管道工具中。它支持各种
输出格式
,包括人性化的控制台输出,以及输出到JSON或HTML文件。
提示#9:使用Postman监视器自动执行测试
您可以使用
Postman监视器
定期自动运行Postman测试,例如每天晚上或每5分钟一次。如果您的任何测试的任何故障系统会自动将收到通知,你甚至可以
集成
与各种第三方服务,如
PagerDuty
,
松弛
,
Datadog
,和
更多
。
邮递员监视器以与邮递员收集运动员相同的熟悉布局显示您的测试结果,因此可以轻松地将结果与Postman应用进行比较。
提示#10:动态控制测试工作流程
默认情况下,邮递员收藏运动员,纽曼和邮递员监视器将按顺序在您的收藏中运行每个请求。但是您可以使用该
postman.setNextRequest()
功能来更改顺序。这允许您有条件地跳过某些请求,重复请求,提前终止收集等。
这是使用Postman的非线性工作流程的第3部分系列中的第一个。
市场上有一些产品可用于创建和执行API工作流程。然而,它们中的大多数都受到线性,非反应性执行的限制。我们知道我们可以创造更有效的东西,并决定为Postman添加工作流程支持。Postman 4.0与命令行伴侣
Newman
结合,现在足够强大,可以帮助您
在收藏集中
创建和执行
非线性工作流
!
这个最新版本建立在我们现有的
Collection Runner上
。它引入了一个名为
postman.setNextRequest
的新函数。从名称中可以看出,您只需要指定后续请求的名称,并且运行程序将负责其余的操作。它具有以下签名:
postman.setNextRequest(“Request Name”);
同时
postman.setNextRequest(null);
终止执行。
下面我们将介绍一个示例工作流程,以便您了解这个工作原理。
这是库珀。他一岁,每天吃三餐。他只允许吃6个预先批准的食物。我们将它们存储在数据库中。库珀非常挑剔。你不能在同一天重复一个项目,除非你想冒发脾气。所以我想在本周初为他生成一个随机的膳食计划。
工作流程:
首先使API调用从数据库中获取Cooper批准的食品列表。
然后它每天创建一个入口,每天7次,每周7天
一天中的所有3餐必须是独一无二的。
如果API调用失败,那么糟糕的库珀就会饿了
如果你好奇,我跑了这个集合,这是Cooper本周吃的东西!
我希望你觉得这很有用。postman.setNextRequest只是一个开始,我们将推出更多的API,以便在Postman的未来几个季度轻松创建复杂的工作流程。敬请关注!通常,postman.setNextRequest参数与请求相关联,可以在预请求或测试脚本中设置。在多于一个作业的情况下,考虑最后一个设定值。如果postman.setNextRequest不存在,则运行程序默认为线性执行并移动到下一个请求。
更新:使用Postman的非线性工作流程的第2部分和第3部分
获取一个返回的HTML文件进行校验
我们包括一个名为
CheerioJS
的新图书馆。Cheerio模拟了jQuery的核心API和功能,而不需要浏览器或DOM。这种方法在Postman内部使用时看起来相当整洁。看看测试脚本中的以下代码示例:
1
2
3
4
5
6
7
8
9
10
|
var html,
titleText;
// load the response body as HTML using cheerio
// and using cheerio's jQuery like .find API, get the H1 tag
html = cheerio(responseBody);
titleText = html.find('h1').text();
// add a test that ensures that there is some H1 content
tests["page must have h1 heading"] = Boolean(titleText);
|
上述代码从HTML响应中提取标题,并测试它是否有一些文本。该代码将不得不通过简单地更换使用jQuery的工作
cheerio
有
jQuery
。总之,如果你知道你在jQuery的方式,你也知道啦啦啦!
newman-cheerio
1
require
(
'newman'
).
run
({
2
// pass a collection that fetches HTML
3
collection
: {
4
item
: [{
5
request
:
'http://httpbin.org/html'
,
6
event
: [{
7
listen
:
'test'
,
8
script
: {
9
type
:
'text/javascript'
,
10
// add a script that checks whether heading H1 is present in HTML
11
exec
: [
12
'tests["response body received"] === !!responseBody;'
,
13
'var html = cheerio(responseBody);'
,
14
'console.log("Heading H1: " + html.find("h1").text());'
,
// log it
15
'tests["html has h1 heading"] = !!html.find("h1").text();'
16
]
17
}
18
}]
19
}]
20
},
21
abortOnFailure
:
true
// ensures run stops abruptly when any error occurs.
22
})
23
// log all runtime console to real console
24
.
on
(
'console'
,
function
(e, args) {
25
console
.
log
.
apply
(
console
, args.
messages
);
26
})
27
// on complete mark the same
28
.
once
(
'done'
,
function
(e) {
29
console
.
log
(
'run complete '
+
(e
?
'with'
:
'without'
)
+
' errors'
);
30
e
&&
console
.
log
(e);
// log error
31
});
EventEmitter
_events
:
Object {console: EE, done: EE}
EventEmitter Prototype
"Heading H1: Herman Melville - Moby-Dick"
"run complete without errors"