让接口自动化测试更简单

HTTP 接口测试很简单,不管工具、框架、还是平台,只要很的好的几个点就是好工具。

  1. 测试数据问题:比如删除接口,重复执行还能保持结果一致,必定要做数据初始化。
  2. 接口依赖问题:B 接口依赖 A 的返回值,C 接口依赖 B 接口的返回值。
  3. 加密问题:不同的接口加密规则不一样。有些用到时间戳、md5、base64、AES,如何提供种能力。
  4. 断言问题:有些接口返回的结构体很复杂,如何灵活的做到断言。

对于以上问题,工具和平台要么不支持,要么很麻烦,然而框架是最灵活的。

unittest/pytest + requests/https 直接上手写代码就好了,既简单又灵活。

那么同样是写代码,A 框架需要 10 行,B 框架只需要 5 行,然而又不失灵活性,那我当然是选择更少的了,毕竟,人生苦短嘛。

seldom 适合个人接口自动化项目,它有以下优势。

  • 可以写更少的代码
  • 自动生成 HTML/XML 测试报告
  • 支持参数化,减少重复的代码
  • 支持生成随机数据
  • 支持 har 文件转 case
  • 支持数据库操作

这些是 seldom 支持的功能,我们只需要集成 HTTP 接口库,并提供强大的断言即可。seldom 2.0 加入了 HTTP 接口自动化测试支持。

Seldom 兼容 Requests API 如下:

Seldom VS Request+unittest

先来看看 unittest + requests 是如何来做接口自动化的:

  1. import unittest

  2. import requests

  3. class TestAPI(unittest.TestCase):

  4. def test_get_method(self):

  5. payload = {'key1': 'value1', 'key2': 'value2'}

  6. r = requests.get("http://httpbin.org/get", params=payload)

  7. self.assertEqual(r.status_code, 200)

  8. if __name__ == '__main__':

  9. unittest.main()

这其实已经非常简洁了。同样的用例,用 seldom 实现。

  1. # test_req.py

  2. import seldom

  3. class TestAPI(seldom.TestCase):

  4. def test_get_method(self):

  5. payload = {'key1': 'value1', 'key2': 'value2'}

  6. self.get("http://httpbin.org/get", params=payload)

  7. self.assertStatusCode(200)

  8. if __name__ == '__main__':

  9. seldom.main()

主要简化点在,接口的返回数据的处理。当然,seldom 真正的优势在断言、日志和报告。

har to case

对于不熟悉 Requests 库的人来说,通过 Seldom 来写接口测试用例还是会有一点难度。于是,seldom 提供了har 文件转 case 的命令。

首先,打开 fiddler 工具进行抓包,选中某一个请求。

然后,选择菜单栏:file -> Export Sessions -> Selected Sessions...

 选择导出的文件格式。

点击next 保存为demo.har 文件。

最后,通过seldom -h2c 转为demo.py 脚本文件。

 
  1. > seldom -h2c .\demo.har

  2. .\demo.py

  3. 2021-06-14 18:05:50 [INFO] Start to generate testcase.

  4. 2021-06-14 18:05:50 [INFO] created file: D:\.\demo.py

demo.py 文件。

  1. import seldom

  2. class TestRequest(seldom.TestCase):

  3. def start(self):

  4. self.url = "http://httpbin.org/post"

  5. def test_case(self):

  6. headers = {"User-Agent": "python-requests/2.25.0", "Accept-Encoding": "gzip, deflate", "Accept": "application/json", "Connection": "keep-alive", "Host": "httpbin.org", "Content-Length": "36", "Origin": "http://httpbin.org", "Content-Type": "application/json", "Cookie": "lang=zh"}

  7. cookies = {"lang": "zh"}

  8. self.post(self.url, json={"key1": "value1", "key2": "value2"}, headers=headers, cookies=cookies)

  9. self.assertStatusCode(200)

  10. if __name__ == '__main__':

  11. seldom.main()

运行测试

打开 debug 模式seldom.run(debug=True) 运行上面的用例。

  1. > python .\test_req.py

  2. 2021-04-29 18:19:39 [INFO] A run the test in debug mode without generating HTML report!

  3. 2021-04-29 18:19:39 [INFO]

  4. __ __

  5. ________ / /___/ /___ ____ ____

  6. / ___/ _ \/ / __ / __ \/ __ ` ___/

  7. (__ ) __/ / /_/ / /_/ / / / / / /

  8. /____/\___/_/\__,_/\____/_/ /_/ /_/

  9. -----------------------------------------

  10. @itest.info

  11. test_get_method (test_req.TestAPI) ...

  12. ----------- Request ---------------

  13. url: http://httpbin.org/get method: GET

  14. ----------- Response ️ -------------

  15. type: json

  16. {'args': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-608a883c-7b355ba81fcd0d287566405a'}, 'origin': '183.178.27.36', 'url': 'http://httpbin.org/get?key1=value1&key2=value2'}

  17. ok

  18. ----------------------------------------------------------------------

  19. Ran 1 test in 0.619s

  20. OK

通过日志/报告都可以清楚的看到。

  • 请求的方法
  • 请求 url
  • 响应的类型
  • 响应的数据
更强大的断言

断言接口返回的数据是我们在做接口自动化很重要的工作。

assertJSON

接口返回结果如下:

 
  1. {

  2. "args": {

  3. "hobby": [

  4. "basketball",

  5. "swim"

  6. ],

  7. "name": "tom"

  8. }

  9. }

我的目标是断言name 和 hobby 部分的内容。seldom 可以针对JSON文件进行断言。

  1. import seldom

  2. class TestAPI(seldom.TestCase):

  3. def test_assert_json(self):

  4. payload = {'name': 'tom', 'hobby': ['basketball', 'swim']}

  5. self.get("http://httpbin.org/get", params=payload)

  6. assert_json = {'args': {'hobby': ['swim', 'basketball'], 'name': 'tom'}}

  7. self.assertJSON(assert_json)

运行日志

  1. test_get_method (test_req.TestAPI) ...

  2. ----------- Request ---------------

  3. url: http://httpbin.org/get method: GET

  4. ----------- Response ️ -------------

  5. type: json

  6. {'args': {'hobby': ['basketball', 'swim'], 'name': 'tom'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-608a896d-48fac4f6139912ba01d2626f'}, 'origin': '183.178.27.36', 'url': 'http://httpbin.org/get?name=tom&hobby=basketball&hobby=swim'}

  7. Assert data has not key: headers

  8. Assert data has not key: origin

  9. Assert data has not key: url

  10. ok

  11. ----------------------------------------------------------------------

  12. Ran 1 test in 1.305s

  13. OK

seldom 还会提示你还有哪些字段没有断言。

assertPath

接口返回数据如下:

  1. {

  2. "args": {

  3. "hobby":

  4. ["basketball", "swim"],

  5. "name": "tom"

  6. }

  7. }

seldom 中可以通过 path 进行断言:

 
  1. import seldom

  2. class TestAPI(seldom.TestCase):

  3. def test_assert_path(self):

  4. payload = {'name': 'tom', 'hobby': ['basketball', 'swim']}

  5. self.get("http://httpbin.org/get", params=payload)

  6. self.assertPath("name", "tom")

  7. self.assertPath("args.hobby[0]", "basketball")

assertSchema

有时并不关心数据本身是什么,而是需要断言数据的类型。 assertSchema 是基于 jsonschema实现的断言方法。

jsonschema: https://json-schema.org/learn/

接口返回数据如下:

  1. {

  2. "args": {

  3. "hobby":

  4. ["basketball", "swim"],

  5. "name": "tom",

  6. "age": "18"

  7. }

  8. }

seldom 中可以通过利用jsonschema 进行断言:

  1. import seldom

  2. class TestAPI(seldom.TestCase):

  3. def test_assert_schema(self):

  4. payload = {"hobby": ["basketball", "swim"], "name": "tom", "age": "18"}

  5. self.get("/get", params=payload)

  6. schema = {

  7. "type": "object",

  8. "properties": {

  9. "args": {

  10. "type": "object",

  11. "properties": {

  12. "age": {"type": "string"},

  13. "name": {"type": "string"},

  14. "hobby": {

  15. "type": "array",

  16. "items": {

  17. "type": "string"

  18. },

  19. }

  20. }

  21. }

  22. },

  23. }

  24. self.assertSchema(schema)

是否再次感受到了 seldom 提供的断言非常灵活,强大。

接口数据依赖

在场景测试中,我们需要利用上一个接口的数据,调用下一个接口。

  1. import seldom

  2. class TestRespData(seldom.TestCase):

  3. def test_data_dependency(self):

  4. """

  5. Test for interface data dependencies

  6. """

  7. headers = {"X-Account-Fullname": "bugmaster"}

  8. self.get("/get", headers=headers)

  9. self.assertStatusCode(200)

  10. username = self.response["headers"]["X-Account-Fullname"]

  11. self.post("/post", data={'username': username})

  12. self.assertStatusCode(200)

seldom 提供了self.response用于记录上个接口返回的结果,直接拿来用即可。

数据驱动

seldom 本来就提供的有强大的数据驱动,拿来做接口测试非常方便。

@data

  1. import seldom

  2. from seldom import data

  3. class TestDDT(seldom.TestCase):

  4. @data([

  5. ("key1", 'value1'),

  6. ("key2", 'value2'),

  7. ("key3", 'value3')

  8. ])

  9. def test_data(self, key, value):

  10. """

  11. Data-Driver Tests

  12. """

  13. payload = {key: value}

  14. self.post("/post", data=payload)

  15. self.assertStatusCode(200)

  16. self.assertEqual(self.response["form"][key], value)

@file_data

创建data.json数据文件

  1. {

  2. "login": [

  3. ["admin", "admin123"],

  4. ["guest", "guest123"]

  5. ]

  6. }

通过file_data实现数据驱动。

  1. import seldom

  2. from seldom import file_data

  3. class TestDDT(seldom.TestCase):

  4. @file_data("data.json", key="login")

  5. def test_data(self, username, password):

  6. """

  7. Data-Driver Tests

  8. """

  9. payload = {username: password}

  10. self.post("http://httpbin.org/post", data=payload)

  11. self.assertStatusCode(200)

  12. self.assertEqual(self.response["form"][username], password)

更过数据文件 (csv/excel/yaml),参考

随机生成测试数据

seldom 提供随机生成测试数据方法,可以生成一些常用的数据。

  1. import seldom

  2. from seldom import testdata

  3. class TestAPI(seldom.TestCase):

  4. def test_data(self):

  5. phone = testdata.get_phone()

  6. payload = {'phone': phone}

  7. self.get("http://httpbin.org/get", params=payload)

  8. self.assertPath("args.phone", phone)

更过类型的测试数据,参考

数据库操作

seldom 支持 sqlite3、MySQL 数据库操作。

连接数据库

连接 sqlit3 数据库

  1. from seldom.db_operation import SQLiteDB

  2. db = SQLiteDB(r"D:\learnAPI\db.sqlite3")

连接 MySQL 数据库(需要)

  1. 安装 pymysql 驱动
> pip install pymysql
  1. 链接
  2. from seldom.db_operation import MySQLDB

  3. db = MySQLDB(host="127.0.0.1",

  4. port="3306",

  5. user="root",

  6. password="123",

  7. database="db_name")

操作方法
  • delete_data

删除表数据。

db.delete_data(table="user", where={"id":1})
  • insert_data

插入一条数据。

  1. data = {'id': 1, 'username': 'admin', 'password': "123"},

  2. db.insert_data(table="user", data=data)

  • select_data

查询表数据。

  1. result = db.select_data(table="user", where={"id":1, "name": "tom"})

  2. print(result)

  • update_data

更新表数据。

db.update_data(table="user", data={"name":"new tom"}, where={"name": "tom"})
  • init_table

批量插入数据,在插入之前先清空表数据。

  1. datas = {

  2. 'api_event': [

  3. {'id': 1, 'name': '红米Pro发布会'},

  4. {'id': 2, 'name': '可参加人数为0'},

  5. {'id': 3, 'name': '当前状态为0关闭'},

  6. {'id': 4, 'name': '发布会已结束'},

  7. {'id': 5, 'name': '小米5发布会'},

  8. ],

  9. 'api_guest': [

  10. {'id': 1, 'real_name': 'alen'},

  11. {'id': 2, 'real_name': 'has sign'},

  12. {'id': 3, 'real_name': 'tom'},

  13. ]

  14. }

  15. db.init_table(datas)

  • close

关闭数据库连接。

db.close()
总结:

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

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

软件测试面试文档

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

 

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新model开发记录

模型使用 -- 用blender导出为 fbx ,修改渲染方式(点击模型->Materials->Extract Materials(将材质从fbx中 单独提取出来了)->Materials 选择 Shader -> SimpleURPToonLitExample 点开脸的材质,勾选第一条) 解决角色…

【C++的奇迹之旅(二)】C++关键字命名空间使用的三种方式C++输入输出命名空间std的使用惯例

文章目录 📝前言🌠 C关键字(C98)🌉 命名空间🌠命名空间定义🌉命名空间使用 🌠命名空间的使用有三种方式:🌉加命名空间名称及作用域限定符🌠使用using将命名空间中某个成员…

MATLAB绘制堆叠填充图--巧用句柄

MATLAB绘制堆叠填充图–巧用句柄 目录 MATLAB绘制堆叠填充图--巧用句柄1. 主要原理讲解1.1 主要函数1.2 句柄原理 2. 绘图示例2.1 准备数据2.2 绘制堆叠填充图-使用句柄控制图形属性2.3 设置填充颜色和样式2.4 添加标题和标签2.5 绘图效果 3. 结语 堆叠填充图是一种常见的数据可…

StringBuffer与StringBuilder

1.区别 (1). String : 不可变字符序列. (2). StringBuffer : 可变字符序列.线程安全,但效率低. (3). StringBuilder : 可变字符序列.线程不安全,但效率高. 既然StringBuffer与StringBuilder都是可变字符序列,但二者咋区分开呢&#xff1f…

Dimitra:基于区块链、AI 等前沿技术重塑传统农业

根据 2023 年联合国粮食及农业组织(FAO)、国际农业发展基金(IFAD)等组织联合发布的《世界粮食安全和营养状况》报告显示,目前全球约有 7.35 亿饥饿人口,远高于 2019 年的 6.13 亿,这意味着农业仍…

碳素光线疗法与宠物健康

碳素光线与宠物健康 生息在地球上的所有动物、在自然太阳光奇妙的作用下、生长发育。太阳光的能量使它们不断进化、繁衍种族。现在、生物能够生存、全仰仗于太阳的光线。太阳光线中、包含有动物健康所需要的极为重要的波长。因此、和户外饲养的动物相比、在室内喂养的观赏动物、…

【机器学习300问】59、计算图是如何帮助人们理解反向传播的?

在学习神经网络的时候,势必会学到误差反向传播,它对于神经网络的意义极其重大,它是训练多层前馈神经网络的核心算法,也是机器学习和深度学习领域中最为重要的算法之一。要正确理解误差反向传播,不妨借助一个工具——计…

初始C语言最后一章《编译、链接与预处理详解》

前言 感谢老铁们的陪伴和支持,初始C语言专栏在本章内容也是要结束了,这创作一路下来也是很不容易,如果大家对 Java 后端开发感兴趣,欢迎各位老铁来我的Java专栏!当然了,我也会更新几章C语言实现简单的数据结…

从C到C++:深入理解基础语法差别

C基础语法讲解 前言1.输入输出2.命名空间2.1命名空间的理解:2.2命名空间的使用方式 3.缺省参数3.1概念:3.2分类:半缺省函数注意事项: 3.3使用案例:顺序表的初始化 4.函数重载4.1参数重载类型类型: 5.引用5.…

C++刷题篇——05静态扫描

一、题目 二、解题思路 注意:注意理解题目,缓存的前提是先扫描一次 1、使用两个map,两个map的key相同,map1:key为文件标识,value为文件出现的次数;map2:key为文件标识,va…

性能测试必备docker环境准备

在当今快速发展的软件开发领域,docker作为一种开源的容器化技术,已经成为提高应用部署效率、实现快速、一致的环境配置的重要工具。而性能测试,则是确保软件应用在各种负载和压力条件下表现良好的关键步骤。二者的结合,为软件开发…

基于springboot酒店管理平台

摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于酒店管理平台系统当然也不能排除在外,随着网络技术的不断成熟,带动了酒店管理平台系统,它彻底改变了过…

手写Spring框架(上)浅出

手写Spring框架 准备工作Spring启动和扫描逻辑实现依赖注入的实现Aware回调模拟实现和初始化机制模拟实现BeanPostProcessor (Bean的后置处理器) 模拟实现Spring AOP 模拟实现 准备工作 准备一个空的工程创建spring的容器类,它是Spring IOC理念的实现,负…

目标检测:数据集划分 XML数据集转YOLO标签

文章目录 1、前言:2、生成对应的类名3、xml转为yolo的label形式4、优化代码5、划分数据集6、画目录树7、目标检测系列文章 1、前言: 本文演示如何划分数据集,以及将VOC标注的xml数据转为YOLO标注的txt格式,且生成classes的txt文件…

web学习笔记(五十一)

目录 1. post请求和get请求的区别 2. CORS 跨域资源共享 2.1 什么是同源 2.2 什么是同源策略 2.3 如何实现跨域资源共享 2.4 使用 cors 中间件解决跨域问题 2.5 JSONP 接口 2.6 实现 JSONP 接口的步骤 1. post请求和get请求的区别 传参方式不同:get请求参数…

NOSQL - Redis的简介、安装、配置和简单操作

目录 一. 知识了解 1. 关系型数据库与非关系型数据库 1.1 关系型数据库 1.2 非关系型数据库 1.3 区别 1.4 非关系型数据库产生背景 1.5 NOSQL 与 SQL的数据记录对比 2. 缓存相关知识 2.1 缓存概念 2.2 系统缓存 2.3 缓存保存位置及分层结构 二 . redis 相关知识 1.…

虚拟机下的Ubuntu系统,NAT网卡连接不上网络的问题

文章目录 解决办法1解决办法2解决办法3Ubuntu20.04桥接网卡和NAT网卡不能同时使用问题解决 本博主花了许久时间解决这个NAT网卡上网问题,如果你试过网上所有教程,检测了Windows环境和Ubuntu环境没问题,无法启动系统服务、ping网络失败、重置虚…

为什么感觉张宇 25 版没 24版讲得好?

很多同学反映:25版,讲得太散了, 知识点太多,脱离了基础班。 三个原因: 1. 25版改动很大,课程没有经过打磨; 2. 因为24考试难度增加,所以改动的总体思路是“拓宽基础”:即把部分强…

这些生活中常用的东西到底要怎么寄?

寄生活中这些常见的“大家伙”,不用发愁啦! 看看德邦快递专业包装,如何保驾护航。 01、行李怎么寄? 如果是装有物品的行李箱:1.使用气泡膜包裹物品,轮子部位加强缓冲物防护; 2.放入适配纸箱&am…

Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01

Natural Language Processing with Attention Models Course Certificate 本文是学习这门课 Natural Language Processing with Attention Models的学习笔记,如有侵权,请联系删除。 文章目录 Natural Language Processing with Attention ModelsWeek 01…