Postman接口测试/接口自动化实战教程

 

一、API 自动化测试

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

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

仅仅做到这些还不能够满足一个系统的开发,或者说过于琐碎,你仍需要频繁地在开发环境,测试环境,生产环境中来回切换。单一的请求也不够,你需要维护系统所有 API 的请求,并且每个请求还带有不同的 querystring 和 body。

二、Collection

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

  • 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。不过都是付费功能,免费版有次数限制

三、文档

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

对于 GET 请求,Postman 上可以添加对该字段的描述,生成文档。
对于 POST 以及 PUT 请求,如果 Content-Type 是 form-data 或者 x-www-form-urlencoded 可以添加描述生成文档。不过如今传递 json 更方便灵活,所以 application/json 也会有很多,而且 json 又是不能添加注释的。如果需要对 json 添加文档说明的话,可以添加冗余字段 _{key}.comment 标明注释

 
  1. {

  2. "id": 128,

  3. "_id.comment": "id",

  4. "page": 10,

  5. "_page.comment": "页数"

  6. "pageSize": 15,

  7. "_pageSize.comment": "每页条数"

  8. }

不过这样冗余字段过多,更好的解决方案是在测试中对请求进行 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。

 
  1. // 响应成功

  2. pm.test('Status code is 200', () => {

  3. pm.response.to.have.status(200)

  4. })

  5. // 响应成功 chai.expect

  6. pm.test('Status code is 200', () => {

  7. chai.expect(pm.response).to.have.property('code', 200)

  8. })

  9. // 校验响应数据

  10. pm.test('Page is 100', () => {

  11. const jsonData = pm.response.json()

  12. chai.expect(jsonData.page).to.eql(100)

  13. })请注明出处。

六、Json Schema

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

建议对所有 GET 响应进行 json-schema 校验,一来校验数据,二来也可以作为文档使用,使用 tv4 校验 json

 
  1. pm.test("User info", () => {

  2. const jsonData = pm.response.json()

  3. const schema = {

  4. title: 'UserInfo',

  5. discription: '用户信息',

  6. type: 'object',

  7. required: ['age', 'email', 'name'],

  8. properties: {

  9. age: {

  10. description: '年龄',

  11. type: 'number',

  12. mininum: 0,

  13. },

  14. email: {

  15. description: '邮箱',

  16. type: 'string'

  17. },

  18. name: {

  19. description: '姓名',

  20. type: 'string'

  21. }

  22. }

  23. }

  24. pm.expect(tv4.validate(jsonData, schema)).to.eql(true)

  25. })

同样对于请求也可以添加 json 校验,不过更复杂一些,因为 postman 没有直接给出获取全部请求参数的api,需要自己解析和计算

  1. // 获取 application/json 中的数据

  2. const json = JSON.stringify(pm.request.body.raw)

  3. // 获取 GET query string 的数据

  4. const qs = pm.request.url.query.toObject()

如果 postman 可以根据请求参数的 json-schema 自动生成数据就好了…

  • 参考
    json-schema.org
    tv4 Documentaion
    chai bdd - API
    postman sandbox api reference
七、测试请求参数

一个请求带有若干参数,如 GET 的 querystring(search) 以及 POST 的 body,不同的参数会有不同的响应。

假设一个请求不同参数返回的 json schema 完全不同,则可以写成两个 Request 分开测试。如果返回的 json schema 相同,只是值不同,则需要考虑传递了哪些参数,参数是多少。

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

伪代码如下:

  1. const url = '/api/users'

  2. const query = {

  3. name: 'san',

  4. age: 12,

  5. sex: 'MALE'

  6. }

  7. // 注意query数据需要校验,防止 SQL 注入

  8. 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

如下:

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

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

  3. if (name) {

  4. pm.test('Items should match the name', () => {

  5. const jsonData = pm.response.json()

  6. expect(_.uniq(jsonData.rows.map(row => row.name))).to.eql([name])

  7. })

  8. }

  9. // 冗余代码有些多,postman不知道支不支持自建 snipets

  10. if (age) {

  11. pm.test('Items should match the age', () => {

  12. const jsonData = pm.response.json()

  13. expect(_.uniq(jsonData.rows.map(row => row.age))).to.eql([age])

  14. })

  15. }

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

 
  1. const query = {

  2. name: 'san',

  3. age: 12,

  4. sex: 'MALE'

  5. }

  6. const sql = `select * from users where name like ${query.name} and age < ${query.age} and sex = ${query.sex}`

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

当然对于后端也是不友好的,因为需要对你传入的每个 query 来进行处理,而且以后每添加一个筛选字段,都需要手动改一下。

可以由前端自行决定需要筛选的数据,比如使用类似于 mongo 的检索语法。

graphql 是相当酷的,值得尝试一下

 
  1. const query = {

  2. name: {

  3. $like: 'san'

  4. },

  5. age: {

  6. $lt: 12

  7. },

  8. sex: 'MALE'

  9. }

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

八、测试多次请求

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

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

  • using csv and json files in the postman collection runner
九、集成测试

单个API测试通过后,需要把所有请求集成在一起进行测试。这时候出现了两个问题
1、如何确保API依赖
2、API之间如何传递数据

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

在 postman 中有三种作用域的数据,data,environment,global。在请求中用 {{}} 占位符替代。

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

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

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

  2. pm.test('There is a token', () => {

  3. const jsonData = pm.response.json()

  4. pm.expect(jsonData.token).to.a('string')

  5. pm.environment.set('token', jsonData.token)

  6. })

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

十、测试Collection

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

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

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

 
  1. pm.test('Response is right', () => {

  2. // status code: 2XX

  3. pm.response.to.be.success

  4. })

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

  6. // ...

  7. })

十一、持续集成

当可以测试 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 的 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 来集成到项目中

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习打卡:day05

day5 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day538、函数的初体验39、函数的基础定义语法函数的定义注意事项 40、函数的基础定义案例练习41、函数的传入参数42、函数的传入参数案例练习——升…

毕业年薪30W起!25届最近5年浙江大学自动化考研院校分析

浙江大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、历年真题PDF 七、初试大纲复试大纲 八、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、考试科目…

揭秘招生简章的制作方法

一年一度的招生季即将来临&#xff0c;各大院校纷纷摩拳擦掌&#xff0c;准备迎接新的学子。对于学校而言&#xff0c;招生简章是其对外宣传的重要窗口&#xff0c;它直接关系到学校的招生效果和声誉。那么&#xff0c;如何制作一份既吸引人又实用的招生简章呢&#xff1f;下面…

【leetcode--字母异位词分组】

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:np collections.defaultdict(list)for st in strs:name "".join(sorted(st))np[name].append(st)return list(np.values()) collections.defaultdict(list)创建字典类型&#xff…

Git代码冲突原理与三路合并算法

Git代码冲突原理 Git合并文件是以行为单位进行一行一行合并的&#xff0c;但是有些时候并不是两行内容不一样Git就会报冲突&#xff0c;这是因为Git会帮助我们进行分析得出哪个结果是我们所期望的最终结果。而这个分析依据就是三路合并算法。当然&#xff0c;三路合并算法并不…

Flowable-决策表设计器

✨✨✨ 最好用的Flowable决策表设计器 ✨✨✨ 最好用的Flowable流程设计器 本文中内容和案例出自贺波老师的书《深入Activiti流程引擎&#xff1a;核心原理与高阶实战》&#xff0c;书中的介绍更全面、详细&#xff0c;推荐给大家。 深入Activiti流程引擎

C++ 31 之 静态成员变量

#include <iostream> #include <string.h> using namespace std;// 特点: // 1.在编译阶段就分配了内存空间 // 2.类内声明&#xff0c;在类外进行初始化 // 3.所有对象共享一份静态成员数据 class Students01{ public:static int s_a; // 静态成员变量int s_b; };…

LSS 和 BEVDepth算法解读

前言 当前BEV的研究大都基于深度学习的方法&#xff0c;从组织BEV特征信息的方式来看&#xff0c;主流方法分属两类&#xff1a;自底向上方法和自顶向下方法。 自底向上方法比较早的代表工作是LSS&#xff0c;后来BEVDet、BEVDepth等也是基于LSS的框架来进行优化。自底向上方…

电子画册制作与传统画册相比,有哪些优势?

在当今数字化时代&#xff0c;电子画册作为一种新兴的媒体形式&#xff0c;其制作与传统画册相比具有显著的优势。以下是对这些优势的详细探讨。 首先&#xff0c;电子画册的制作过程通常更加便捷和经济。相较于传统画册需要经历的繁琐的印刷过程&#xff0c;电子画册的制作大多…

【C++课程学习】:类和对象(拷贝构造和运算符重载)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 ✍拷贝构造&#xff1a; &#x1f349;特点一&#xff1a; &#x1f349;特点二&#xff1a; &…

(三十)Flask之wtforms库【剖析源码上篇】

每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 &#x1f525;&#x1f525;本文已收录于Flask框架从入门到实战专栏&#xff1a;《Flask框架从入…

45.Python-web框架-Django - 开始建立第一个项目

目录 1.django是什么&#xff1f; 2.Pycharm 社区版&#xff0c;还是专业版&#xff1f; 3.开始django&#xff0c;Pycharm专业版 创建一个Django项目 运行一个Django项目 运行方法一&#xff0c;命令行的方式 运行方法二&#xff0c;配置Django Server的方式 4.django尊…

gpio-0设置成输出失败的原因

原因 spi驱动先设置gpio-0成了输出&#xff1b; 但是后面其他驱动&#xff0c;使用of_property_read_u32获取设备树节点的属性时&#xff0c;没去判断返回值&#xff1b;而直接使用参数返回的0&#xff0c;导致gpio-0又被设置成了输入 实例 正常的如下&#xff0c;gpio显示…

入职3年-我如何做一名AI产品经理(文末福利)

引言 从2021年校招加入京东开始&#xff0c;我一直从事AI产品经理的工作&#xff0c;有幸见证了AI行业的热情从一台台服务器烧到了全世界各个角落&#xff0c;也见证了京东AI中台团队的影响力如何一步步的扩大。从21年的迷茫到24年的坚定&#xff0c;很庆幸我正走在适合自己的…

【C++】类的默认成员函数

类的默认成员函数 类的六个默认成员函数构造函数构造函数的概念构造函数的特性 析构函数析构函数的概念析构函数的特性 构造函数与析构函数的调用顺序拷贝构造拷贝构造的概念拷贝构造的特性赋值运算符重载运算符重载赋值运算符重载前置与后置重载输入输出流重载 const修饰成员实…

高精度减法

高精度减法 两个高精度整数的减法题目思路实现代码实现 两个任意符号的高精度加减法 两个高精度整数的减法 高精度指的是数字的大小非常非常大&#xff0c;最多能有10的5次方 的 位数。 本次计算的两个数均为 正数&#xff0c;如何求负数会在最后提到。 题目 给定两个正整数…

解决浏览器缩放的时候,重新设置滚动条的位置,使页面滚动条固定悬浮在页面底部

项目场景&#xff1a; 浏览器调试页面兼容页面时&#xff0c;缩放页面宽度&#xff0c;整体超出时滚动条出现在页面最底部&#xff0c;不是悬浮在页面下面&#xff0c;只有滚动到最底部才出现&#xff0c;需要的是悬浮在页面底部&#xff0c;不是滚动到最下面才出现 解决方案…

java面试整合全套

什么是Java &#xff08;定义 优点&#xff09; java是一个平台&#xff0c;由jvm和Java应用编程接口构成的一门面向编程语言。 不仅吸收了C语言的各种优点&#xff0c;还摒弃了c语言里面的多继承,指针等概念&#xff0c;因此java的特征主要有功能强大和简单易用的特征。 jav…

FPGA Verilog模块化设计入门篇一

随着电子技术的快速发展&#xff0c;现场可编程门阵列&#xff08;FPGA&#xff09;已成为现代电子系统设计中不可或缺的一部分。FPGA的灵活性、可重构性和高性能使得它成为处理复杂算法、加速数据处理和实现特定功能的理想选择。然而&#xff0c;随着系统复杂性的增加&#xf…

go-zero整合Excelize并实现Excel导入导出

go-zero整合Excelize并实现Excel导入导出 本教程基于go-zero微服务入门教程&#xff0c;项目工程结构同上一个教程。 本教程主要实现go-zero框架整合Excelize&#xff0c;并暴露接口实现Excel模板下载、Excel导入、Excel导出。 go-zero微服务入门教程&#xff1a;https://blo…