Postman 自动化测试实践一文通

Postman 是什么?

Postman 简介

Postman 是一款 RESTFul Client ,提供了标准的 RESTFul 请求的接口;并且,在请求之上提供了 Runner 来批量运行请求,提供了对应的 Test 模块,以支持针对接口进行测试和断言。


Postman 其实已经发布很久了,我印象中从 2015 年就零零散散有在用 Postman 来进行一些接口的调试工作。如今四年已过,Postman 也从最早的仅提供 Chrome 拓展版发展到提供多个原生版本的应用。大大的拓展其能力。

为什么是 Postman ,而不是其他工具

之所以使用 Postman ,主要是 Postman 本身有一些非常不错的功能,比如:

无需搭建环境:Postman 本身就是一个完整的环境,里面包含测试等功能,如果你不需要通过命令行来进行调度的话,直接使用客户端就可以完成所有的测试内容。降低了搭建环境的痛苦。支持以 Collection 来管理请求:我们可以将所有的接口按照功能、用途等进行分类,然后去执行请求,从而实现批量的请求管理。提供了 Pre-request Script 功能
: Pre-Request Script 可以在请求执行前进行操作。比较常见的场景,比如说接口需要鉴权,那么你可以将获取 Token 的代码放在 Pre-request Script 中。或者是这个接口需要的一些参数,你需要从另外一个地方获取时,就可以在这里设置。提供了多环境的支持:多环境支持的功能可以让我们随时切换不同的环境参数,比如你可以将 API 的 Endpoint 放在环境变量中,这样你就可以通过切换环境来测试本地开发环境、云上测试环境、生产环境的接口,可以有效的减少工作量。提供了 Runner 的批量运行测试的功能:Runner 为用户提供了可视化批量运行测试的能力。毕竟,并不是每一个人都懂得代码的,不少测试人员他们只懂少量的代码,如果他们也想批量测试,如果没有 Runner ,就非常的麻烦。支持测试的导入导出、链接分享等能力:Postman 可以将测试导出为一个个 JSON,而且还可以生成唯一链接,你可以直接将链接分享出去,让别人运行你的测试。如果你需要别人运行你的测试时,直接分享链接就可以了。测试环境内置了不少类库:Postman 的测试环境中内置了不少类库和帮助函数,可以方便你进行各种各样的测试,比如 Lodash、cheerio、tv4 、CryptoJS 等。
支持 Newman 自动化测试:接口测试是一个挺枯燥的事情,如果能够命令来控制执行,那会是非常爽的事情,刚好,newman 是支持的。...

综合上述的一些原因,我最终选择了 Postman 。

如果你并不想要一个专业的测试工具,只是想要一个 RESTFul Client,可以试试看 Insomnia。

Postman 的客户端选择

Postman 提供了两个不同的版本,一个是原生的版本,也是官方较为推荐的版本,另一个版本是 Chrome 拓展的版本。前者相比于后者,提供更加强大的能力,后者则根植于 Chrome 生态内,对于系统本身的侵入性较小。二者的差距主要是 Chrome 拓展的版本受限于 Chrome 应用本身的 API ,所以在功能上略有缺失,具体如下:

Web应用缺失的功能:

Cookies 的支持:受限于 Chrome 的 WebApp 的 API,WebApp 的版本无法修改 Cookies,如果你需要修改 Cookies ,那么就需要使用原生的应用。内建代理的支持:在 Chrome 的 WebApp 中,由于其本身并没有完整的运行环境,所以 WebApp 的应用的代理依赖于 Chrome 浏览器的设置,你的浏览器使用什么样的代理,你的测试就会使用什么样的代码。这样可能不利于你针对请求进行抓包。
更加宽泛的 Header 设定:受限于 Chrome 中 WebApp 的 API 限制,在 Web App 中,你的 Origin 和 User-Agent 是无法修改的,如果你需要修改就需要使用原生的 App。...

好在,我们如果想要完成一个测试,基本的的功能无论是 Chrome 插件的版本还是独立安装的版本都是支持的,因此,你可以根据自己的喜好来选择适合你的版本。

Postman 与测试

在上一部分,我们了解了什么是 Postman ,接下来,我们来看看 Postman 与测试的关系。

Postman 测试什么?

测试有很多不同的细分类型,从开发人员是否看代码可以分为黑盒测试和白盒测试;从测试的阶段来看有单元测试、集成测试、系统测试等。对于 Postman 来说,他所适合的,是进行API 测试,也是我们在这一篇文章将要分享的。

Postman 本身是一个 RESTFul Client,在此基础上,加入了对接口测试的支持,为每一个请求引入了断言库,可以很好的完成对接口的测试,因此,我们用它来做接口测试,也只做它最擅长的接口测试。

接口测试的意义

测试不同于开发、产品的阶段,测试所达成的目标是帮助产品确定是否符合用户需求,以及保证产品的质量,属于锦上添花而非雪中送炭的项目。因此,在一整个项目的开发周期过程中,测试往往也是最后被配齐的团队。

而且,软件开发不仅仅是一个技术的军备竞赛,更是成本管控的项目,我们到底应该做什么样的测试,应当根据产品的类型、产品的阶段、人员的配备、可以调控的资源等来进行控制。

不同类型的测试所带来的金钱成本和时间成本用一张图来表示就是这样的。


对于一个开发团队来说,如果你的资源不足以支撑你去花费大量的时间和精力去做单元测试,又担心 UI 测试可能会有一些遗漏,那么投入产出比高的接口测试绝对是最佳选择。

相比于单元测试,接口测试只需要针对接口进行测试,测试量相对小一些。而相比于 UI 测试,可控性要更高,毕竟返回的接口都是 JSON,更加容易进行测试。

使用 Postman 进行测试

说了那么多湿货,接下来,开始我们的干货内容。

使用 Postman 来进行测试

创建集合与测试

首先,我们来使用 Postman 进行测试,我们将要使用 httpbin.org 来进行测试。

首先,创建一个集合


然后,创建一个 GET 请求,并发送请求


接下来,我们来针对这个请求进行测试。

使用 pre-request>

点击上方的 Pre-request Script,


然后在其中加入这样一行代码

pm.environment.set("gitchat_verify", "this-is-a-verify");



然后回到 Params 中,我们可以添加一个新的 key ,叫 verify,其 value 为 {{gitchat_verify}}

再重新执行发送请求


我们可以看到,返回值中的 args 中显示出了我们的 verify。

这样,我们实现了在请求前去抓取一些参数,这个功能可以用于与多个 API 进行联调时,需要获取请求参数的场景。

编写测试

接下来,我们来编写测试,点击上面的 tests,进入到测试界面。

在测试界面的右侧为我们提供了一些常用的代码。你可以点击这里的代码来应用。

比如检测返回状态码应为 200 的代码如下

pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});



添加完成代码后,保存,并重新执行。


你可以看到我们的测试已经执行完成并通过了。

让测试报错

我们可以修改一下请求类型,让请求类型从 Get 变为 Post,再次请求,这样我们的返回码就会从 200 变为 405 ,这时我们的测试就会报错了。


添加更多测试

除了检测返回码以外,我们还可以检测更多的东西,比如,我们可以检测服务器返回为 verify 值是否和我们传上去的一致:

let verify = pm.environment.get("gitchat_verify");
tests["verify 值相同"] = verify === pm.response.json().args.verify

通过这样一行代码,我们就完成了我们自己设置的 verify 和服务器返回的 verify 的值是否相同。

细心的你可能发现了,两种测试的代码似乎差距很大

一般来说,tests['提示语句'] = xxxx === xxxx 会应用于一些非常简单的检验场景,比如值是否相等。只要等号后面的语句返回值为 true ,这个 tests 就会通过,并在下方显示我们所定义的提示语句。如果为 false ,测试就不通过。


而 pm.test('提示语句',callback) 这种风格,会用于一些较为复杂的判断。

进行 JSON Schema 校验测试

除了检测值的是否相等,我们常用的还要检测一个 JSON 的结构是否发生了变化,如果其架构发现了变化,我们就需要对应的调整客户端的代码,因此,我们需要对 JSON 的 Schema 进行校验。

Postman 的 JSON 校验使用的是 tv4,其使用的校验格式是 JSON Schema ,你可以在这里找到他们官方的一些 Example,通过 Example 来理解 JSON Schema,从而构建你自己的 Schema。

比如说,HttpBin 的返回值的 JSON Schema 校验代码如下可以是这样的

var schema = {
"type":"object",
"required": [ "args", "headers","origin","url" ],
"properties":{
"args":{
"type":"object",
"required": [ "verify" ],
},
"headers":{
"type":"object",
"required": [ "Accept", "Accept-Encoding","Cache-Control","Host","Postman-Token","User-Agent" ],
"properties":{
"Accept":{
"type":"string"
},
"Accept-Encoding":{
"type":"string"
},
"Cache-Control":{
"type":"string"
},
"Host":{
"type":"string"
},
"Postman-Token":{
"type":"string"


},
"User-Agent":{
"type":"string"
}
}
},
"origin":{
"type":"string"
},
"url":{
"type":"string"
}
}
};
pm.test('Schema is valid', function() {
pm.expect(tv4.validate(pm.response.json(), schema)).to.be.true;
});

在上述这段 Schema 中,我使用了 type 来校验每个字段的类型,并使用 required 确保我想要的字段都是有的,并使用 properties 来校验子属性的属性。这样,只要 API 发送了变化,我所需要的字段如果出现了类型的变化或者缺失,我跑一遍测试马上就知道了。

使用 Runner 来进行批量测试

在测试时,我们经常会需要用到批量测试,比如要测试一组连贯的 API 接口,在 Postman 中,也可以非常简单的实现。

首先,你在 collection 中创建一个新的测试, 比如这里创建一个 Post 测试,并添加了一个测试返回状态码的测试。


点击执行,可以跑通测试后。点击上面的 Runner 按钮,进入到 Runner 界面。


在 Runner 界面,选择你要执行的 collection,


然后点击下方的 Start Run ,就可以看到运行的测试,及相关的结果。

这里你可以设置重复执行的次数,来进行多次测试。



如果需要调整执行的顺序,你可以在 request 的管理界面通过拖拽进行修改,或者使用postman.setNextRequest("B") 方法来通过代码指定。

使用 newman 来执行测试

使用 newman 需要你先自行安装 Node.js 环境。

Postman 最为强大,也是我最为看重的点,就是 newman 了,Newman 可以让原本 GUI 才能运行的测试,变成使用命令行来测试,这样,我们的测试就可以通过代码来进行管理,我们的测试就可以和代码本身进行整合,非常的方便。

newman 的使用非常的简单,你只需要执行如下命令来安装 newman

npm install -g newman

安装完成后,执行如下命令来运行测试即可。

newman run xxxx.json

除了执行本地的测试,还可以是测试链接,你可以在 Collection 上右击,选择 分享链接,并生成一个链接。



将这个链接作为 newman 的参数,也可以运行测试,比如

newman run https://www.getpostman.com/collections/7185b2153732d5ded053

使用命令运行测试特别适合于你要执行别人的测试的场景。

使用 Travis CI 来执行测试 ( package.json 依赖版)

由于 newman 可以通过 npm 来安装,所以,你想要在 travis-ci 上去运行 newman 来执行自动化测试也就简单了许多。

进入项目目录(可以新建一个,或者考虑将 newman 的测试直接引入到你们现有的项目中,如果你们的项目不是 Node 项目,那么几乎不可能会造成项目的依赖的冲突),执行 npm init -y 来生成一个 package.json 的配置文件。


然后创建一个 tests 目录,来存放测试的 collection ,将你的测试代码导出到 tests 文件夹中。

然后执行 npm install newman --save 来安装 newman 。

你也可以将其安装在 devDependencies 中,这样的话,不与生产环境的依赖干扰。

然后,修改 package.json 文件,将其中的 test 的值改为 newman run tests/xxx.json


这样你就可以执行 npm test 来运行 newman 进行测试了。


接下来,在你的项目根目录创建一个 .travis.yml 文件,并在其中加入如下代码

language: node_js
sudo: false
node_js:
- "8"
- "10"
cache:
directories:
- "node_modules"
script:
- npm test

然后,把你的代码推送到 Github ,并开启 Travis-CI 的自动构建,就可以自动测试了。

演示项目:https://github.com/bestony/newman-travis-ci-demo 演示测试:https://travis-ci.com/bestony/newman-travis-ci-demo/jobs/182603167

使用 Travis CI 来执行测试 ( travis.yml 版)

除了定义 package.json 依赖以外,你还可以考虑使用 travis.yml 来进行测试的设置。

你同样需要创建 tests 目录,并导出你的测试集合文件,不同的是,这次你只需要创建一个.travis.yml 文件即可,在其中加入如下内容,同样可以完成测试。而且,这样的测试更加简洁,不具有侵入性。

language: node_js
node_js:
- "8"


- "10"
install:
- npm install newman
before_script:
- node --version
- npm --version
- node_modules/.bin/newman --version
script:
- node_modules/.bin/newman run tests/xxx.json

使用 newman 来并行执行测试

Postman 应用本身是无法支持并行测试的,不过你可以使用 newman 来进行并行测试。方法也很简单。

只需要使用下面的这段代码,就可以并行执行测试了。

var path = require('path'), // 用于读取文件
async = require('async'), // 引入 async 库
newman = require('newman'),
options = {
collection: path.join(__dirname, 'sample-collection.json') // 配置需要运行的测试集合,提前在 Postman 中将测试导出来。
},
// 定义运行函数来运行测试
parallelCollectionRun = function (done) {
newman.run(options, done);
};
// 并行执行测试
async.parallel([
parallelCollectionRun,
parallelCollectionRun,
parallelCollectionRun
],
// 错误处理
function (err, results) {
err && console.error(err);
results.forEach(function (result) {
var failures = result.run.failures;
console.info(failures.length ? JSON.stringify(failures.failures, null, 2) :


`${result.collection.name} ran successfully.`);
});
});

上面这段代码中的 options 你可以根据你自己的需要去进行调整,比如,使用 URL 来测试,具体的参数说明你可以看:https://github.com/postmanlabs/newman#api-reference

代码出处:https://github.com/postmanlabs/newman/blob/develop/examples/parallel-collection-runs.js

Postman 使用的常见问题

1. 我不懂代码可以用 Postman 么?

Postman 本身只是一个 RESTFul Client ,你可以直接使用其来进行接口的调试。如果你希望加入一些测试的内容,那么需要稍微懂一些 JavaScript 代码,来写断言。

2. 如何将 A 请求中的值传递给 B 请求用?

这其实是一个非常常用的场景,比如说,一些接口需要用户登陆,如果没有办法将数据从 A 传递给 B,在使用时就非常的麻烦,你需要自己手动复制 Token 到 B 中去执行,效率非常的低。

不过,在 Postman 中,你可以很方便的实现。

Postman 中是有环境这样的一个概念的,你可以针对不同的测试场景来创建不同的环境,并借助环境中的数据可以被多个请求利用的特性来在不同的请求中传递数据。


你只需要在 A 请求中发送请求,并获到需要传递的数据,将其提取出来,然后使用设置环境变量的代码,将对应的数据设置为环境变量,在需要使用的地方使用 Mustache 语法进行调用即可。

比如说,下面这一行代码就是将返回值中的 Token 设置为一个环境变量 token,

// 返回值结构


{
"data":{
"token": "this is a token"
}
}
// 获取 token,并将其设置为 环境变量的代码
pm.environment.set("token", pm.response.json().data.token);

然后,你在另外一个请求中使用 {{token}} 来调用即可。


在使用这个方法时,你需要注意的是,A 与 B 的请求顺序是不能错的,不然 B 在请求时,环境变量还没有被设置,自然就会出错了。而想要实现控制,你需要在A的测试代码中加入这样一行

postman.setNextRequest("B")

例子如下:


3. 如果请求需要使用 Cookie 认证怎么测试呢?

接口需要 Cookie 认证的场景也非常常见,事情的思路与 Token 校验的一致,在可以获取到 Cookie 的请求中去拿到对应的 Cookie ,然后将其设置设置为环境变量,并在需要的时候使用。

你可以在 test 环境里执行如下命令来获取 Header 中的 Cookie

let cookie = postman.getResponseHeader("Set-Cookie")

然后,将其设置为环境变量

pm.environment.set("cookie",cookie);

并在需要的地方使用 {{cookie}} 进行调用。

4. Newman 如何产出测试报告?

因为测试工作往往需要和开发部门进行协作,所以测试报告也是非常重要的一个环境。

newman 本身提供了四种不同的 reporter ,你可以通过安装不同的拓展来进行支持。


总结

我自己本身也并不是一个专业的测试,使用 Postman 帮助我更好的去完成自己的工作,对于一些非测试人员来说,倘若有这样的一个学习成本不高,同时还能有较高收益的事情来学习,何乐而不为呢?

如果你有任何问题,都可在下方评论区留言提问,我们一同交流 Postman 的使用技巧。