前言

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 requests
self.get() requests.get()
self.post() requests.post()
self.put() requests.put()
self.delete() requests.delete()

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

我的目标是断言namehobby 部分的内容。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数据库操作。

sqlite3 MySQL
delete_data() delete_data()
insert_data() insert_data()
select_data() select_data()
update_data() update_data()
init_table() init_table()
close() close()

连接数据库

连接sqlit3数据库

  1. from seldom.db_operation import SQLiteDB
  2. db = SQLiteDB(r"D:\learnAPI\db.sqlite3")

连接MySQL数据库(需要)

  1. 安装pymysql驱动
  1. > pip install pymysql
  1. 链接
  1. from seldom.db_operation import MySQLDB
  2. db = MySQLDB(host="127.0.0.1",
  3. port="3306",
  4. user="root",
  5. password="123",
  6. database="db_name")

操作方法

  • delete_data

删除表数据。

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

更新表数据。

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

关闭数据库连接。

  1. db.close()

最后,基于seldom 实现接口自动化测试的项目:https://github.com/defnngj/pyrequest2

seldom 2.0 让接口自动化测试更简单的更多相关文章

  1. APICloud数据云3.0 -- 让后端业务更简单

    近年来,各类移动端应用层出不穷,app.小程序已成为企业业务数字化的必然选择,围绕互联网产品的技术创新与开发者生态,正在历经行业发展的又一次革新. APICloud作为国内领先的移动应用开发平台,一直 ...

  2. Jmeter接口自动化测试:简单使用步骤

    好处:不需要页面就可以提前介入测试,实施成本低,修改量少,相对于UI自动化来说更为稳定 1. 下载略过 2. 使用步骤 创建线程组合控制器(Jmeter基本操作) 针对http协议的接口增加Sampl ...

  3. 使用 JsonPath 完成接口自动化测试中参数关联和数据验证(Python语言)

    背景: 接口自动化测试实现简单.成本较低.收益较高,越来越受到企业重视 restful风格的api设计大行其道 json成为主流的轻量级数据交换格式 痛点: 接口关联 也称为关联参数.在应用业务接口中 ...

  4. 接口自动化测试框架-AIM2.0

    跳转到3.0版本https://www.cnblogs.com/df888/p/12031649.html AIM是我用python搭建的第一款接口自动化测试框架,随着技术的提升,框架也在升级,故有了 ...

  5. 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~

    一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...

  6. 接口自动化测试的"开胃小菜"---简单黑客攻击手段

    Web应用系统的小安全漏洞及相应的攻击方式 接口自动化测试的"开胃小菜" 1   写作目的 本文讲述一个简单的利用WebAPI来进行一次基本没有破坏力的“黑客”行为. 主要目的如下 ...

  7. 如何简单实现接口自动化测试(基于 python) 原博主地址https://blog.csdn.net/gitchat/article/details/77849725

    如何简单实现接口自动化测试(基于 python) 2017年09月05日 11:52:25 阅读数:9904 GitChat 作者:饿了么技术社区 原文:如何简单实现接口自动化测试(基于 python ...

  8. 记录python接口自动化测试--简单总结一下学习过程(第十目)

    至此,从excel文件中循环读取接口到把测试结果写进excel,一个简易的接口自动化测试框架就完成了.大概花了1周的时间,利用下班和周末的时间来理顺思路.编写调试代码,当然现在也还有很多不足,例如没有 ...

  9. 简单实现接口自动化测试(基于python+unittest)

    简单实现接口自动化测试(基于python+unittest) 简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手,一步步调整优化接口调用,以及增加基本的结果判断,讲解Pytho ...

随机推荐

  1. 将文件服务器及域控制器从2003迁移至Windows Server 2008 R2

    (一)背景环境: 当前,多数小企业仍然使用windows server2003 系统做域控制器及文件服务器,由于windows server 2003在多年使用之后变得卡顿,且存在异常的系统错误及诟病 ...

  2. JSON简单了解

    JSON简单了解 简介 JSON (JavaScript Object Notation):一种简单的数据格式,比xml更轻巧.JSON 是 JavaScript 原生格式,这意味着在 JavaScr ...

  3. 02 CTF WEB 知识梳理

    1. 工具集 基础工具 Burpsuit, Python, FireFox(Hackbar, FoxyProxy, User-Agent Swither .etc) Burpsuit 代理工具,攻击w ...

  4. 软负载Nginx和硬负载F5的优缺点对比

    对于数据流量过大的网络中,往往单一设备无法承担,需要多台设备进行数据分流,而负载均衡器就是用来将数据分流到多台设备的一个转发器.​ a.软件负载均衡解决方案 在一台服务器的操作系统上,安装一个附加软件 ...

  5. font

    font属性简写 front: font-style font-variant font-weight font-size/line-height font-family 说明: 值之间空格隔开 注意 ...

  6. [刷题] PTA 7-64 最长对称子串

    7-64 最长对称子串 我的代码: 1 #include<stdio.h> 2 #include<string.h> 3 #define N 1001 4 5 int main ...

  7. [刷题] 剑指offer 面试题18:删除链表节点

    要求 给定单向链表的头指针和一个节点指针,在O(1)时间内删除该节点 常规思路:从头节点a开始顺序遍历,发现p指向要删除的节点i,然后把p的m_pNext指向i的下一个节点j,时间复杂度O(n) O( ...

  8. 在/etc/profile下配置java的环境变量

    在/etc/profile下配置java的环境变量 原创 Java 作者:xiaoyan5686670 时间:2016-01-18 14:30:28  6152  0 以root用户编辑:#vi /e ...

  9. Telnet 对比 SSH

    # 命令行 ssh 比teltet 加密好 图形 vnc只能传递图形 不能传递声音,linux为服务端,vnc客户端为windows 和linux vnc是windows连linux rdp是linu ...

  10. Canal和Otter讨论二(原理与实践)

    上次留下的问题 问题一: 跨公网部署Otter 参考架构图 解析 ​ a. 数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工 ...