接口自动化测试,完整入门篇
目录
- 1. 什么是接口测试
- 2. 基本流程
- 3. 需求分析
- 4. 用例设计
- 5. 脚本开发
- 6. 结果分析
- 7. 完整脚本
- 8. 参考资料
1. 什么是接口测试
顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主要分为功能测试,性能测试,稳定性测试,安全性测试等。
在分层测试的“金字塔”模型中,接口测试属于第二层服务集成测试范畴。相比UI层(主要是WEB或APP)自动化测试而言,接口自动化测试收益更大,且容易实现,维护成本低,有着更高的投入产出比,是每个公司开展自动化测试的首选。
下面我们以一个HTTP接口为例,完整的介绍接口自动化测试流程:从需求分析到用例设计,从脚本编写、测试执行到结果分析,并提供完整的用例设计及测试脚本。

2. 基本流程
基本的接口功能自动化测试流程如下:
需求分析 -> 用例设计 -> 脚本开发 -> 测试执行 -> 结果分析
2.1 示例接口
接口名称:豆瓣电影搜索
接口文档地址:https://developers.douban.com/wiki/?title=movie_v2#search
接口调用示例:
1) 按演职人员搜索:https://api.douban.com/v2/movie/search?q=张艺谋
2) 按片名搜索:https://api.douban.com/v2/movie/search?q=大话西游
3) 按类型搜索:https://api.douban.com/v2/movie/search?tag=喜剧
3. 需求分析
需求分析是参考需求、设计等文档,在了解需求的基础上还需清楚内部的实现逻辑,并且可以在这一阶段提出需求、设计存在的不合理或遗漏之处。
如:豆瓣电影搜索接口,我理解的需求即是支持对片名,演职人员及标签的搜索,并分页返回搜索结果。
4. 用例设计
用例设计是在理解接口测试需求的基础上,使用MindManager或XMind等思维导图软件编写测试用例设计,主要内容包括参数校验,功能校验、业务场景校验、安全性及性能校验等,常用的用例设计方法有等价类划分法,边界值分析法,场景分析法,因果图,正交表等。
针对豆瓣电影搜索接口功能测试部分,我们主要从参数校验,功能校验,业务场景校验三方面,设计测试用例如下:

5. 脚本开发
依据上面编写的测试用例设计,我们使用python+nosetests框架编写了相关自动化测试脚本。可以完整实现接口自动化测试、自动执行及邮件发送测试报告功能。
5.1 相关lib安装
必要的lib库如下,使用pip命令安装即可:
pip install nose pip install nose-html-reporting pip install requests
5.2 接口调用
使用requests库,我们可以很方便的编写上述接口调用方法(如搜索q=刘德华,示例代码如下):
#coding=utf-8 import requests import jsonurl = 'https://api.douban.com/v2/movie/search' params=dict(q=u'刘德华') r = requests.get(url, params=params) print 'Search Params:\n', json.dumps(params, ensure_ascii=False) print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)
在实际编写自动化测试脚本时,我们需要进行一些封装。如下代码中我们对豆瓣电影搜索接口进行了封装,test_q方法只需使用nosetests提供的yield方法即可很方便的循环执行列表qs中每一个测试集:
class test_doubanSearch(object):@staticmethoddef search(params, expectNum=None):url = 'https://api.douban.com/v2/movie/search'r = requests.get(url, params=params)print 'Search Params:\n', json.dumps(params, ensure_ascii=False)print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)def test_q(self):# 校验搜索条件 qqs = [u'白夜追凶', u'大话西游', u'周星驰', u'张艺谋', u'周星驰,吴孟达', u'张艺谋,巩俐', u'周星驰,大话西游', u'白夜追凶,潘粤明']for q in qs:params = dict(q=q)f = partial(test_doubanSearch.search, params)f.description = json.dumps(params, ensure_ascii=False).encode('utf-8')yield (f,)
我们按照测试用例设计,依次编写每个功能的自动化测试脚本即可。
5.3 结果校验
在手工测试接口的时候,我们需要通过接口返回的结果判断本次测试是否通过,自动化测试也是如此。
对于本次的接口,我们搜索“q=刘德华”,我们需要判断返回的结果中是否含有“演职人员刘德华或片名刘德华”,搜索“tag=喜剧”时,需要判断返回的结果中电影类型是否为“喜剧”,结果分页时需要校验返回的结果数是否正确等。完整结果校验代码如下:
class check_response():@staticmethoddef check_result(response, params, expectNum=None):# 由于搜索结果存在模糊匹配的情况,这里简单处理只校验第一个返回结果的正确性if expectNum is not None:# 期望结果数目不为None时,只判断返回结果数目eq_(expectNum, len(response['subjects']), '{0}!={1}'.format(expectNum, len(response['subjects'])))else:if not response['subjects']:# 结果为空,直接返回失败assert Falseelse:# 结果不为空,校验第一个结果subject = response['subjects'][0]# 先校验搜索条件tagif params.get('tag'):for word in params['tag'].split(','):genres = subject['genres']ok_(word in genres, 'Check {0} failed!'.format(word.encode('utf-8')))# 再校验搜索条件qelif params.get('q'):# 依次判断片名,导演或演员中是否含有搜索词,任意一个含有则返回成功for word in params['q'].split(','):title = [subject['title']]casts = [i['name'] for i in subject['casts']]directors = [i['name'] for i in subject['directors']]total = title + casts + directorsok_(any(word.lower() in i.lower() for i in total),'Check {0} failed!'.format(word.encode('utf-8')))@staticmethoddef check_pageSize(response):# 判断分页结果数目是否正确count = response.get('count')start = response.get('start')total = response.get('total')diff = total - startif diff >= count:expectPageSize = countelif count > diff > 0:expectPageSize = diffelse:expectPageSize = 0eq_(expectPageSize, len(response['subjects']), '{0}!={1}'.format(expectPageSize, len(response['subjects'])))
5.4 执行测试
对于上述测试脚本,我们使用nosetests命令可以方便的运行自动化测试,并可使用nose-html-reporting插件生成html格式测试报告。
运行命令如下:
nosetests -v test_doubanSearch.py:test_doubanSearch --with-html --html-report=TestReport.html
5.5 发送邮件报告
测试完成之后,我们可以使用smtplib模块提供的方法发送html格式测试报告。基本流程是读取测试报告 -> 添加邮件内容及附件 -> 连接邮件服务器 -> 发送邮件 -> 退出,示例代码如下:
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipartdef send_mail():# 读取测试报告内容with open(report_file, 'r') as f:content = f.read().decode('utf-8')msg = MIMEMultipart('mixed')# 添加邮件内容msg_html = MIMEText(content, 'html', 'utf-8')msg.attach(msg_html)# 添加附件msg_attachment = MIMEText(content, 'html', 'utf-8')msg_attachment["Content-Disposition"] = 'attachment; filename="{0}"'.format(report_file)msg.attach(msg_attachment)msg['Subject'] = mail_subjetmsg['From'] = mail_usermsg['To'] = ';'.join(mail_to)try:# 连接邮件服务器s = smtplib.SMTP(mail_host, 25)# 登陆s.login(mail_user, mail_pwd)# 发送邮件s.sendmail(mail_user, mail_to, msg.as_string())# 退出s.quit()except Exception as e:print "Exceptioin ", e
6. 结果分析
打开nosetests运行完成后生成的测试报告,可以看出本次测试共执行了51条测试用例,50条成功,1条失败。

失败的用例可以看到传入的参数是:{"count": -10, "tag": "喜剧"},此时返回的结果数与我们的期望结果不一致(count为负数时,期望结果是接口报错或使用默认值20,但实际返回的结果数目是189。赶紧去给豆瓣提bug啦- -)

7. 完整脚本
豆瓣电影搜索接口的完整自动化测试脚本,我已上传到的GitHub。下载地址:test_demo/test_douban at master · lovesoo/test_demo · GitHub
下载完成之后,使用如下命令即可进行完整的接口自动化测试并通过邮件发送最终的测试报告:
python test_doubanSearch.py
最终发送测试报告邮件,截图如下:

8. 参考资料
1) requests: Requests: 让 HTTP 服务人类 — Requests 2.18.1 文档
2) nosetests: Testing with nose — nose 1.3.7 documentation
3) nose-html-reporting: nose-html-reporting · PyPI
相关文章:

接口自动化测试,完整入门篇
目录 1. 什么是接口测试2. 基本流程3. 需求分析4. 用例设计5. 脚本开发6. 结果分析7. 完整脚本8. 参考资料1. 什么是接口测试 顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及…...

利用ControlNet重新定义你的AI姿势
利用ControlNet重新定义你的AI姿势 前段时间给大家分享了如何利用colab实现AI绘画自由,现在Stable Diffusion WebUI Colab TW又更新了不少新功能。最重要的是可以通过谷歌硬盘的快捷方式导入模型,极大的节省了谷歌硬盘容量。 众所周知,谷歌…...

中医药NER命名实体识别基于SPANNER方式
一个不知名大学生,江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion:2023.3.5 Last edited: 2023.3.5 导读 本文使用SPANNER方式实现对中医药进行实体识别,采用focal loss 进行优化。 本文章作用防止安静…...

Vue必掌握
目录 一、组件通信方式 二、v-if和v-for 三、生命周期 1、描述 2、setup和created谁先执行 3、setup中为什么没有beforeCreate和created 四、双向绑定 v-model 1、定义 2、本质,原理 3、好处 五、如何扩展一个组件 1、mixins 缺点 2、slot插槽 3、e…...
SSM部分
声明式事务 从之前的事务控制的代码中可以看出,是有规律可循,代码的结构基本是确定的,所以框架就可以将固定模式的代码抽取出来,进行相关的封装。 封装起来后,我们只需要在配置文件中进行简单的配置即可完成操作。 …...

【Springboot系列】Springboot接管所有Controller,magic-api源码阅读
系列文章地址:Spring Boot学习大纲,可以留言自己想了解的技术点 最近在项目中使用了一个第三方的包 magic-api,节省了很多的时间,整体来说就是只用写sql就好了,不用写service,controller那些,全部统一处理了。 具体的使用大家可以搜索下,网上到处都是,建议去官网看。…...

二、LED子系统数据结构详解
个人主页:董哥聊技术我是董哥,嵌入式领域新星创作者创作理念:专注分享高质量嵌入式文章,让大家读有所得!文章目录1、核心数据结构1.1 gpio_led_platform_data1.2 gpio_leds_priv1.3 gpio_led1.4 gpio_led_data1.5 led_…...
Kubernetes(11):数据存储详解
在前面已经提到,容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。 Volume是Pod中能够被多个容器访问的共享目录…...
随想录Day43--动态规划: 1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零
最后一块石头重量转化为将一个集合分隔成两个集合,两个集合之间的差值最小,就是最后剩下最小的石头重量。这里可以求集合的一个平均值,如果正好等于平均值,说明可以抵消,这时候重量为0,如果不行,…...
Qt中对TCP粘包的处理
当时用TCP协议传输数据时,经常出现粘包的现象 当服务器向客户端发送数据之后,客户端还没有接收数据的时候,这段时间数据在什么地方? 1、服务器?服务器已经发出数据了 2、网线?数据应该在内存,怎…...
贪心-单调递增的数字
当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时,我们称这个整数是单调递增的。 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9示例 2: 输入: n 1234 输出: 1234示例 3: 输入…...

你真的会用搜索引擎吗?
作为一名在校大学生,对于搜索资料这一件事深有体会,特别是在期末考试突击的时候,如何利用搜索引擎,快速找到自己想要的知识,快速理解这个知识点,想必是每位大学生的必备技能了。 我们在学习一个知识点的过…...

KDCJ-20kV冲击耐压测试仪
一、产品简介 KDCJ-20kV冲击耐压测试仪是电力设备高压试验的基本项目之一,电力设备在设计、制造及修缮之后都要求进行冲击试验以验证或检验。因此,冲击电压试验设备有着广泛的应用,在工厂、研究机构及大专院校的高压试验室中都可以看到不同规…...

【Mybatis源码分析】TypeAliasRegistry源码分析
TypeAliasRegistry源码分析一、引入类型别名二、typeAlias 的三种配置方式三、TypeAliasRegistry源码分析三种配置方式源码解析校验过程Mybatis默认的别名配置四、总结一、引入类型别名 当配置 XML 文件,需要指明Java类型时,类型别名可替代Java类型的全…...
节点高负载
如何判断节点高负载? 可以通过 top 或 uptime 来确定 load 大小,如果 load 小于 CPU 数量,属于低负载,如果大于 CPU 数量 2~3 倍,就比较高了,当然也看业务敏感程度,不太敏感的大于 4 倍算高负载。 排查思路 观察监控:通常不是因为内核 bug 导致的高负载,在卡死之前…...

动态规划(一) part1
T1:一个数组 中的最长 升序 子序列 的长度 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组…...

Ubuntu显卡报错:Failed to initialize NVML Driver/library version mismatch
问题描述 输入指令nvidia-smi的时候,出现如下: Failed to initialize NVML: Driver/library version mismatch看起来好像是版本不匹配,在网上查了很多都没有解决问题,重启也不行,结果证明最好的办法是重新安装cuda。…...
JAVA企业电子采购系统源码:采购过程更规范,更透明
满足采购业务全程数字化, 实现供应商管理、采购需求、全网寻源、全网比价、电子招 投标、合同订单执行的全过程管理。 电子招标采购,是指在网上寻源和采购产品和服务的过程。对于企业和企业主来说,这是个既省钱又能提高供应链效率的有效方法…...

5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世
MWC2023大会召开在即,5GAdvanced产业再添重磅消息!2月15日,高通宣布推出全球首个5GAdvanced-ready基带芯片——骁龙X755G调制解调器及射频系统,支持毫米波和Sub-6GHz频段,带来网络覆盖、时延、能效和移动性等全方位的提…...

基于B站王阿华的视频——为什么当下自媒体都在制造焦虑以及如何摆脱
观后笔记2.0——一些深入的思考 1.情绪大约在两千万年前,哺乳脑统治期间诞生。 2.情绪分为积极情绪和负面情绪。决定某种情绪的出现取决于安全感等级。 自媒体制造负面情绪,想尽办法挑起情绪,吸引流量 安全感充足时,由积极情绪…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...