使用Postman作API自动化测试

Postman API 自动化测试

Postman 最基本的功能用来重放请求,而且配合良好的 response 格式化工具。javascript

高级点的用法可使用 Postman 生成各个语言的脚本,还能够抓包,认证,传输文件。html

仅仅作到这些还不可以知足一个系统的开发,或者说过于琐碎,你仍须要频繁地在开发环境,测试环境,生产环境中来回切换。单一的请求也不够,你须要维护系统全部 API 的请求,而且每一个请求还带有不一样的 querystringbody前端

github地址java

Collection

对服务器端的全部请求按功能或者业务模块进行组织,使用 markdown 对全部请求和示例添加适当的描述,这时候就用到了 Collection。如下是 postman 的一些术语以及组织请求的建议。git

详细参考 Postman SDK Concepts 以及 creating collectionsgithub

  • Collection
    对应一个Application,组内各个成员(server, client, QA)共享一个 Collection。能够对整个 Collection 添加测试,文档。
    对于一开始未在 postman 组织请求的应用,能够设置 Proxy,跑一遍应用,对应用的全部请求进行抓包。
  • Folder (ItemGroup)
    对应一个模块,或者各层级子路由。如 router.use('/users') 全部的请求都在一个 Folder,能够根据路由互相嵌套 Folder。
  • Request (Item)
    对应一个请求,能够添加认证信息。也能够设置代理,进行抓包。详见 capturing http requests
  • Example
    对应一个请求不一样的参数以及响应,用于Mock Server 以及文档。

postman 能够根据 Collection 的结构生成文档与Mock Server。不过都是付费功能,免费版有次数限制。sql

文档

postman 自动生成文档有助于团队协做,解决了手动写文档,以及更新不及时的重大bug。shell

对于 GET 请求,Postman 上能够添加对该字段的描述,生成文档。npm

对于 POST 以及 PUT 请求,若是 Content-Type 是 form-data 或者 x-www-form-urlencoded 能够添加描述生成文档。不过现在传递 json 更方便灵活,因此 application/json 也会有不少,并且 json 又是不能添加注释的。若是须要对 json 添加文档说明的话,能够添加冗余字段 _{key}.comment 标明注释json

{
  "id": 128,
  "_id.comment": "id",
  "page": 10,
  "_page.comment": "页数"
  "pageSize": 15,
  "_pageSize.comment": "每页条数"
}

不过这样冗余字段过多,更好的解决方案是在测试中对请求进行 json 校验,同时充当了一部分文档的功能。毕竟 json-schema 就是用来描述数据使数据更加可读。

以上说到请求,对于响应的文档,能够 json-schema 校验或者每一个字段的描述,以及更多的测试用例表明更多的细节。

Mock

当服务器端尚未写好 API 时,客户端能够根据 Examples 来生成 Mock Server。

建议客户端端本身作 Mock,与项目集成在一块儿,归入版本控制,方便灵活。强烈推荐 json-server,简单好用。

测试

对于每个 Request 都须要有测试用例。验证响应是否成功,响应时间是否过长或者响应 json 的数据类型是否正确。

测试可使用 pm.expect 进行 BDD 测试,风格和 chai 很像,若是熟悉 chai 就很容易上手。

postman 内置了一些第三方库,若是你更喜欢 chai ,能够直接使用,也可使用 pm.expect 底层使用 chai 实现,与 chai BDD API 一致。

postman 也有一些 http 相关的测试 API,如 status code,header, body,而且也提供了一些 snippets。

// 响应成功
pm.test('Status code is 200', () => {
  pm.response.to.have.status(200)
})

// 响应成功 chai.expect
pm.test('Status code is 200', () => {
  chai.expect(pm.response).to.have.property('code', 200)
})

// 校验响应数据
pm.test('Page is 100', () => {
  const jsonData = pm.response.json()
  chai.expect(jsonData.page).to.eql(100)
})

Json Schema

json-schema 能够用来描述 json 信息,使 json 更加易读,同时也能够用来校验 json 的合法性。主流语言都有实现 json-schema 的库。

建议对全部 GET 响应进行 json-schema 校验,一来校验数据,二来也能够做为文档使用,使用 tv4 校验 json

pm.test("User info", () => {
  const jsonData = pm.response.json()
  const schema = {
    title: 'UserInfo',
    discription: '用户信息',
    type: 'object',
    required: ['age', 'email', 'name'],
    properties: {
      age: {
        description: '年龄',
        type: 'number',
        mininum: 0,
      },
      email: {
        description: '邮箱',
        type: 'string' 
      },
      name: {
        description: '姓名',
        type: 'string' 
      }
    }
  }
  pm.expect(tv4.validate(jsonData, schema)).to.eql(true)
})

一样对于请求也能够添加 json 校验,不过更复杂一些,由于 postman 没有直接给出获取所有请求参数的api,须要本身解析和计算

// 获取 application/json 中的数据
const json = JSON.stringify(pm.request.body.raw)

// 获取 GET query string 的数据
const qs = pm.request.url.query.toObject()
若是 postman 能够根据请求参数的 json-schema 自动生成数据就行了...

测试请求参数

一个请求带有若干参数,如 GETquerystring(search) 以及 POSTbody,不一样的参数会有不一样的响应。

假设一个请求不一样参数返回的 json schema 彻底不一样,则能够写成两个 Request 分开测试。若是返回的 json schema 相同,只是值不一样,则须要考虑传递了哪些参数,参数是多少。

一个经典的场景,根据 filter 来筛选符合条件的列表。拿用户列表举例,伪代码以下

const url = '/api/users'
const query = {
  name: 'san',
  age: 12,
  sex: 'MALE'
}
// 注意query数据须要校验,防止 SQL 注入
const sql = `select * from users where name = ${query.name} and age = ${query.age} and sex = ${query.sex}`

一个思路是根据请求的参数进行测试,一段重要的 snipet 是在 postman 中获取 querystring,query 是一种 PropertyList 的数据,定义在 postman-collection - PropertyList。以下

const name = pm.request.url.query.get('name')
const age = pm.request.url.query.get('age')

if (name) {
  pm.test('Items should match the name', () => {
    const jsonData = pm.response.json()
    expect(_.uniq(jsonData.rows.map(row => row.name))).to.eql([name])
  })
}

// 冗余代码有些多,postman不知道支不支持自建 snipets
if (age) {
  pm.test('Items should match the age', () => {
    const jsonData = pm.response.json()
    expect(_.uniq(jsonData.rows.map(row => row.age))).to.eql([age])
  })
}

固然以上 filter 只包含了最简单的场景,其中只涉及到了相等测试。可是有不等以及包含关系呢。

const query = {
  name: 'san',
  age: 12,
  sex: 'MALE'
}
const sql = `select * from users where name like ${query.name} and age < ${query.age} and sex = ${query.sex}`

这种请求参数依赖于先后端的协商交流,固然对测试或者一个不知情的开发来讲很不友好的。

固然对于后端也是不友好的,由于须要对你传入的每一个 query 来进行处理,并且之后每添加一个筛选字段,都须要手动改一下。

能够由前端自行决定须要筛选的数据,好比使用相似于 mongo 的检索语法。

graphql 是至关酷的,值得尝试一下
const query = {
  name: {
    $like: 'san' 
  },
  age: {
    $lt: 12 
  },
  sex: 'MALE'
}

不过这对于测试的开发能力要求也比较高了,测试人员须要解析参数而且测试接口。

测试屡次请求

当对一个函数进行单元测试时,须要大量的输入以及指望输出,在postman中,可使用 data 来模拟屡次输入

data 是一种变量,只能在 Runner 中使用,有必要对每一个 Folder 创建相关的 data file,而且加入版本控制

集成测试

单个API测试经过后,须要把全部请求集成在一块儿进行测试。这时候出现了两个问题

  1. 如何确保API依赖
  2. API之间如何传递数据

请求在 Collection 的顺序就是他们的发起请求的顺序,若是须要强制更改顺序,可使用 setNextRuest()

在 postman 中有三种做用域的数据,dataenvironmentglobal。在请求中用 {{}} 占位符替代。

environment 能够用来更改 HOST,避免在 url 中频繁手动切换本地环境,开发环境和生产环境。另外也能够用来传递数据。

一个常见的场景是项目使用 token 来保存登陆信息,每次请求都须要携带token。能够在登陆的测试代码中设置 token 的环境变量

const url = 'http://{{HOST}}/api/login'

pm.test('There is a token', () => {
  const jsonData = pm.response.json()
  pm.expect(jsonData.token).to.a('string')
  pm.environment.set('token', jsonData.token)
})

const urlNext = 'http://{{HOST}}/api/profile?token={{token}}'

测试Collection

确保依赖后,能够对 Collection 新建一个 Runner,而且引入一个 data 文件来测试全部的请求。对局部的 Folder 也可使用 Runner 以及 data 进行测试。

最新版本的 postman 已经能够支持,为每一个 Postman 新建变量以及 Test

全部的请求都会有一些共同测试,好比测试接口是否响应成功以及以上提到的测试 filter

pm.test('Response is right', () => {
  // status code: 2XX
  pm.response.to.be.success
})

pm.test('Filter is matching', () => {
  // ...
})

持续集成

当能够测试 Collection 后,须要对测试加入版本控制,与项目集成在一块儿,保留测试记录,以便准时定位 bug。能够与 postman 的官方工具 newman 集成在一块儿,可是有一点不方便的是,持续集成仅仅能够保存记录,并不能还原记录。

newman run https://api.getpostman.com/collections/{{collection_uid}}?apikey={{postman-api-key-here}} --environment https://api.getpostman.com/environments/{{environment_uid}}?apikey={{postman-api-key-here}}

对比UI自动化测试

按照个人理解,UI 自动化测试目的是用来测试流程是否通畅,好比登录,注册,退出,若是用例没经过则截屏。可是前端需求的不断变化,加上如今各类前端框架,致使 selector 不是特别容易获取到且流程容易更改。

而API 自动化测试用来测试数据是否正确。并且大部分问题是出在数据问题上,因此 API 自动化测试性价比比较高一些。

总结

  1. 如何编写测试用例

    postman 底层使用 [chai.js](http://chaijs.com/api/bdd/) 的 bdd 语法做为断言库,另外加了一些特有的语法。
  2. 如何debug

    点击菜单栏 View -> Show Devtools (Show Postman Console) 能够查看响应,检查输出,不过不能打断点。对于系统的单个请求,可使用 Proxy 监听请求进行调试。
  3. 如何使用js第三方库对请求就行预处理以及后处理

    好比:
    发送请求时,服务器端要求时间为 timestmap(unix) 的格式,但接口调试时可读性过弱,是否可使用 moment 转化时间。
    收到响应时,也须要 moment 对时间进行解析,得到更好的展示形式。或者使用 lodash 一些函数进行数据的处理。

    能够在 Tests 和 Pre-request Script 中编写脚本对请求以及响应作一些处理。可是不能对数据格式化,好比日期。
    建议先后端交流日期时使用 ISO 格式的字符串,先后端都容易解析,而且可读性强。
  4. 如何管理请求依赖

    好比:
    两个API须要有依赖关系,好比当建立完一个用户后(注册),获取他的我的信息。获取我的信息就须要依赖建立用户这个API。

    使用 Environment Variables 能够管理依赖
  5. 如何设置统一的请求参数

    好比:
    大部分接口都须要统一的 token 参数。

    目前好像没什么办法
  6. 如何集成到服务器端项目中

    若是系统后续版本没有经过API测试,则保留测试记录是很重要的,版本控制能够得知该时间段内的代码变动。以git为例,须要每次提交后运行测试,并保留测试结果。

    可使用 npm 包 newman 来集成到项目中

参考

相关文章
相关标签/搜索