用 Python 为接口测试自动生成用例
基于属性的测试会产生大量的、随机的参数,特别适合为单元测试和接口测试生成测试用例
尽管早在 2006 年 haskell 语言就有了 QuickCheck
来进行“基于属性的测试 ”,但是目前来看这依然是一个比较小众的领域。参考资料有限,本文若有不足,欢迎指正。
目录
1. 基于表的测试
2. 基于属性的测试
3. 如何进行基于属性的测试
4. 在接口测试中自动生成用例
1. 基于表的测试
在过去的实践中,执行测试时通常需要明确的内容(Value):
条件
输入
结果
这些内容可以通过 “判定树” 或者 “判断表” 来表示,然后测试的执行过程变成了这样:
“给定输入 X,我们期望 Y”
可以称为 基于表的测试
在最初,这给了我们测试的方向,但是缺点也非常明显:
你要足够多的 "X->Y" 才能可能覆盖到隐蔽的 bug。
这里请大家思考几个问题:
你是否已经为每一个测试编写了足够多的用例,以至于你十分确定真的不需要再增加用例了
这么多的用例,你编写得是否开心?是否高效?是否愿意继续坚持?
如果以上问题的答案不是 yes,那么基于属性的测试就是你需要掌握的东西!
2. 基于属性的测试
基于属性的测试和基于表的测试,最大的区别可以这样描述:
“给定输入 X 值,我们期望 Y 值”
vs
“给定输入 X 类,我们期望 Y 类”
于是利用工具生成大量的 X 类数据,进行测试,并验证结果是否 Y 类。
值得注意的是:
关注输入的类型,而不是输入的值
根据类型自动生成大量的、随机的输入值
换言之,它在自动的生成测试用例,虽然输入值是随机的,但是值类型符合规范要求
3. 如何进行基于属性的测试
在不同的语言中有不同的工具来实现,比如:
haskell 中的
QuickCheck
、java 中的
quicktheories
python 中的
hypothesis
本文以 python 为例进行演示:
假设有 add 函数,接收两个类型整数参数,并返回它们的相加结果
def add(a: int, b: int) -> int:
pass
首先写出一个简单的测试用例
def test_add():
assert 3 == add(1, 2)
正如前面所说,一个这样的用例,根本没信心覆盖全部的场景,例如:
参数是 0
参数是负数
参数值特别大
其他...
所以接下来怎么办?
改为基于属性的测试:
import hypothesis.strategies as st
from hypothesis import given
@given(st.integers(), st.integers())
def test_add(a, b):
c = add(a, b)
print(f"{a=},{b=}, {c=}")
assert isinstance(c, int)
assert c == a + b
执行结果
a=0,b=0, c=0
a=0,b=0, c=0
a=0,b=0, c=0
a=16926,b=11053, c=27979
a=0,b=0, c=0
a=0,b=0, c=0
a=21010,b=-2732672789497425072, c=-2732672789497404062
a=0,b=0, c=0
a=14554,b=-15956, c=-1402
a=15597,b=0, c=15597
a=15597,b=13, c=15610
a=15597,b=0, c=15597
a=15597,b=15597, c=31194
a=28965,b=-36, c=28929
a=113,b=-36, c=77
a=28929,b=-36, c=28893
a=28929,b=9356, c=38285
a=9356,b=9356, c=18712
a=10278,b=-62, c=10216
a=-62,b=-62, c=-124
a=1625,b=-68244995710046113596363052355575247332, c=-68244995710046113596363052355575245707
a=1625,b=-13143, c=-11518
a=1625,b=1625, c=3250
a=-1940,b=-31868, c=-33808
a=-7,b=1, c=-6
a=-1,b=0, c=-1
a=-1,b=0, c=-1
a=13,b=7245, c=7258
a=13,b=13, c=26
a=-99,b=-18, c=-117
a=-30172,b=66, c=-30106
a=-30172,b=-16940, c=-47112
a=-16940,b=-16940, c=-33880
a=-1233214851,b=-5152, c=-1233220003
a=-5152,b=-5152, c=-10304
a=-16,b=-29706, c=-29722
a=-29706,b=-29706, c=-59412
a=-29706,b=116, c=-29590
a=29696,b=90, c=29786
a=29696,b=29696, c=59392
a=-11446,b=-21185, c=-32631
a=-21185,b=-21185, c=-42370
a=-12,b=16437, c=16425
a=-12,b=16437, c=16425
a=3202,b=53, c=3255
a=3202,b=3202, c=6404
a=-98,b=3, c=-95
a=82691970030325711417874227410289695610,b=1316378701, c=82691970030325711417874227411606074311
a=82691970030325711417874227410289695610,b=82691970030325711417874227410289695610, c=165383940060651422835748454820579391220
a=24100,b=14385, c=38485
a=24100,b=14385, c=38485
a=24100,b=24100, c=48200
a=12293,b=-106, c=12187
a=12293,b=27280, c=39573
a=27280,b=27280, c=54560
a=-18887,b=-5530, c=-24417
a=-18887,b=-18887, c=-37774
a=4738,b=122351151658095310625663643505383743930, c=122351151658095310625663643505383748668
a=-24601163521689169516616964879873921492,b=565838202, c=-24601163521689169516616964879308083290
a=4738,b=122351151658095310625663643281738736058, c=122351151658095310625663643281738740796
a=-96098295006598318424285019062007505,b=25207226, c=-96098295006598318424285019036800279
a=-96098295006598318424285019062007505,b=-1997122225172868107163535967078611096, c=-2093220520179466425587820986140618601
a=-96098295006598318424285019062007505,b=-96098295006598318424285019062007505, c=-192196590013196636848570038124015010
a=-36,b=1190, c=1154
a=-36,b=-4, c=-40
a=-36,b=-36, c=-72
a=2047897602,b=-4641, c=2047892961
a=2047897602,b=2047897602, c=4095795204
a=-1307873608,b=11753, c=-1307861855
a=-1307873608,b=-3308225400997338452, c=-3308225402305212060
a=-1307873608,b=770256249, c=-537617359
a=-1307873608,b=-1307873608, c=-2615747216
a=-4715910568460396013,b=-18622, c=-4715910568460414635
a=16754,b=-6053, c=10701
a=-6053,b=-6053, c=-12106
a=-6053,b=-6053, c=-12106
a=-22264,b=44, c=-22220
a=-22264,b=-22264, c=-44528
a=-86,b=-86, c=-172
a=-86,b=-86, c=-172
a=1794,b=28170, c=29964
a=1794,b=28170, c=29964
a=-93,b=482, c=389
a=-1,b=482, c=481
a=-1,b=-1, c=-2
由结果可知,工具根据参数是整数这一规范,自动生成、执行了大量的测试用例
4. 在接口测试中自动生成用例
接口测试和函数的单元测试非常相似:
输入数据
返回数据
此外接口文档作为前后端、甚至测试开发的对接窗口,对参数的要求约定的更加细致,
以 OpenAPI 为例,每个参数可以有这些属性:
type:数字还是字符串?
format:密码还是电子邮箱?
maxLength:长度不超过多少?
required:是否必填?
in:参数通过什么传递?
其他...
于是为接口生成符合要求的参数就变得非常可行,
再根据OpenAPI中关于响应结果的描述,可以生成断言
一批测试用例就这样自动完成了
举个例子:
import unittest
import requests
from api_tools import APITestCase
class UserCase(APITestCase):
schema = "http://127.0.0.1:7600/openapi.json"
if __name__ == "__main__":
unittest.main()
这是以 unittest 为例进行封装的结果,只需要在 TestCase 中指定 openapi 的内容(或路径),
启动测试框架时,会自动读取、解析接口文档,并生成测试用例
下面是部分执行日志,可以看到:
对接口发送了随机参数,并获得返回值
INFO 2022-04-10 01:02:59,223 : 执行用例 login_login_access_token_post
INFO 2022-04-10 01:02:59,223 : -----调用接口:login_login_access_token_post-----
INFO 2022-04-10 01:02:59,223 : 发送请求>>> :请求数据 = {'userin': {'password': 'bEYtwDZUxdBVThEFOqTz', 'email': 'KEfQnAtTNtwZOXRjoIjp'}}
INFO 2022-04-10 01:02:59,578 : 接收响应 <<<:<Response [400]>
INFO 2022-04-10 01:02:59,578 : -----调用完毕:login_login_access_token_post-----
INFO 2022-04-10 01:02:59,578 : 执行用例 test_token_login_test_token_post
INFO 2022-04-10 01:02:59,578 : -----调用接口:test_token_login_test_token_post-----
INFO 2022-04-10 01:02:59,578 : 发送请求>>> :请求数据 = {}
INFO 2022-04-10 01:03:00,035 : 接收响应 <<<:<Response [200]>
INFO 2022-04-10 01:03:00,035 : -----调用完毕:test_token_login_test_token_post-----
INFO 2022-04-10 01:03:00,035 : 执行用例 sign_up_login_sign_up_post
INFO 2022-04-10 01:03:00,035 : -----调用接口:sign_up_login_sign_up_post-----
INFO 2022-04-10 01:03:00,035 : 发送请求>>> :请求数据 = {'userin': {'password': 'GgzYcOwapTwnkkKVTraE', 'email': 'EJrXlCSNKKjdiVvAOnTM'}}
INFO 2022-04-10 01:03:00,657 : 接收响应 <<<:<Response [200]>
INFO 2022-04-10 01:03:00,657 : -----调用完毕:sign_up_login_sign_up_post-----
INFO 2022-04-10 01:03:00,657 : 执行用例 todo_list_todo_get
INFO 2022-04-10 01:03:00,657 : -----调用接口:todo_list_todo_get-----
INFO 2022-04-10 01:03:00,657 : 发送请求>>> :请求数据 = {}
INFO 2022-04-10 01:03:01,233 : 接收响应 <<<:<Response [200]>
INFO 2022-04-10 01:03:01,233 : -----调用完毕:todo_list_todo_get-----
INFO 2022-04-10 01:03:01,233 : 执行用例 todo_post_todo_post
INFO 2022-04-10 01:03:01,233 : -----调用接口:todo_post_todo_post-----
INFO 2022-04-10 01:03:01,233 : 发送请求>>> :请求数据 = {'todoin': {'title': '', 'is_done': False}}
INFO 2022-04-10 01:03:01,594 : 接收响应 <<<:<Response [200]>
INFO 2022-04-10 01:03:01,594 : -----调用完毕:todo_post_todo_post-----
INFO 2022-04-10 01:03:01,594 : 执行用例 todo_delete_all_todo_delete
INFO 2022-04-10 01:03:01,594 : 执行用例 todo_get_todo__todo_id__get
INFO 2022-04-10 01:03:01,594 : -----调用接口:todo_get_todo__todo_id__get-----
INFO 2022-04-10 01:03:01,594 : 发送请求>>> :请求数据 = {'todo_id': 2451}
INFO 2022-04-10 01:03:02,026 : 接收响应 <<<:<Response [404]>
INFO 2022-04-10 01:03:02,026 : -----调用完毕:todo_get_todo__todo_id__get-----
INFO 2022-04-10 01:03:02,026 : 执行用例 todo_put_todo__todo_id__put
INFO 2022-04-10 01:03:02,026 : -----调用接口:todo_put_todo__todo_id__put-----
INFO 2022-04-10 01:03:02,026 : 发送请求>>> :请求数据 = {'todo_id': 1519, 'todoin': {'title': '', 'is_done': False}}
INFO 2022-04-10 01:03:02,423 : 接收响应 <<<:<Response [404]>
INFO 2022-04-10 01:03:02,423 : -----调用完毕:todo_put_todo__todo_id__put-----
INFO 2022-04-10 01:03:02,423 : 执行用例 todo_delete_todo__todo_id__delete
鉴于篇幅有限,暂时介绍这么多,
如果你对这个话题依旧有兴趣,可在公众号窗口中回复:PBT
原创不易,喜欢请星标+点赞+在看,关注本公众号,不错过技术干货,谢谢鼓励!
欢迎关注我的公众号“ 测试开发研习社”,专注Python开发及测试技术
用 Python 为接口测试自动生成用例相关推荐
- Python: Git Log自动生成Release Notes,并调用Outlook发送至邮件
Python: Git Log自动生成Release Notes,并调用Outlook发送至邮件 主要功能 先上图 生成ReleaseNotes 邮件: 生成ReleaseNotes Text: 关键 ...
- Python PaddleNLP实现自动生成虎年藏头诗
这篇文章主要介绍了利用Python PaddleNLP实现自动生成虎年藏头诗功能,文中的示例代码讲解详细,感兴趣的同学可以跟随小编一起试一试.Python编程学习资料点击免费领取 目录 1.paddl ...
- Python实现文章自动生成
Python实现文章自动生成 下面的Python程序实现了通过从网页抓取一篇文章,然后根据这篇文章来生成新的文章,这其中的原理就是基于概率统计的文本分析. 过程大概就是网页抓取数据->统 ...
- python数据字典ppt_Python3自动生成MySQL数据字典的markdown文本的实现
为啥要写这个脚本 五一前的准备下班的时候,看到同事为了做数据库的某个表的数据字典,在做一个复杂的人工操作,就是一个字段一个字段的纯手撸,那速度可想而知是多么的折磨和锻炼人的意志和耐心,反正就是很耗时又 ...
- 基于Python的Excel自动生成软件——以工作日志为例
在日常工作中,每日需要填写一次工作日志,且每月的工作日志保存在一个xlsx文件的不同sheet中. 虽然可手动进行每日工作日志sheet的创建,但长此以往费时费力,遂萌生出使用python自动生成工作 ...
- 怎么自学python自动化测试-python自动化测试如何自动生成测试用例?
传统的用例需要测试或者开发人员将用户的操作用代码表示出来,通过断言判断是否和预期一致,写测试用例也占用了部分时间,加上版本迭代测试用例的维护成本也较高,于是基于无埋点的需求相结合来检测埋点,及时告警, ...
- 用python写一个自动生成春联的软件,打包exe
文章目录 唠叨一下 效果展示 代码 打包exe可执行文件 唠叨一下 最近不是快过年了,Python写对联挺火的,但是代码又不是人人都用,那就直接写个界面打包一下呗~ 主要实现只要运行后输入上联下联.横 ...
- python可视化界面自动生成_python生成界面
广告关闭 云服务器1核2G首年99年,还有多款热门云产品满足您的上云需求 前言对于一些 python 脚本,我们想把它打包给其他人使用,不是黑色的命令行框,而是打包成一个有界面的程序包给别人,让普通用 ...
- 如何用python自动改试卷_利用Python和Jinja2自动生成试卷
一.概述 Jinja2是Python 3下一个被广泛应用的模版引擎,它的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能.其中最显著的一个是增加了沙箱执行功能和可选的自动转义功能 ...
最新文章
- 编写nios-shell时想到的问题-回车vs换行
- Dell服务器相关操作
- windows下 网络命令(待续)
- assign与weak区别(面试)
- CS224d lecture 9札记
- 51nod 1428 活动安排问题 (贪心+优先队列)
- 如何优雅的使用全球最大同性社交网站
- C语言 - 判断素数的函数
- Eclipse语言包在官网下载不了-解决方案
- 测试 tolua 例子 TestErrorStack
- 从零開始搭建微信硬件开发环境全过程——1小时掌握微信硬件开发流程
- base64字符串转换为图片
- Unity给小鳄鱼洗澡2D流体水实现
- 一款网页游戏外挂开发-数据抓包
- 开启愉快的路由之旅:广工校园网Wifi
- php判断字符串长度 strlen()与mb_strlen()函数
- 一个月怎么赚到5万块?
- [转载]一篇经典的求职经历博客,值得深入研究和学习
- Web前端大作业—个人网页(html+css+javascript)
- spark.DataFrame离群值处理
热门文章
- 如何编写linux批处理文件,Linux和Windows下的批处理文件编写
- python mongodb aggregate聚合
- 非智能手机java_非智能手机操作系统两大介绍【图文】
- Win7codecs解码包实现.avi等视频文件播放
- 抖音无人直播项目技术丨三大玩法你知道吗?
- 【文字游戏之猜单词】
- PostgreSQL插件开发1
- 后缀是lnk是什么文件_后缀名为lnk的文件是什么文件?急!!
- QLineEdit 控制输入格式——正则表达式与输入掩码
- 全球最常用密码名单公布:“123456”排第二;谷歌神秘项目曝光:AI写代码,抢程序员饭碗;WSL GA发布|极客头条