接口测试难点:
- 测试数据问题:比如删除接口,重复执行还能保持结果一致,必须要有数据清洗。
- 接口依赖问题:B 接口依赖 A 的返回值,C 接口依赖 B 接口的返回值。
- 加密问题:不同的接口加密规则不一样。有些用到时间戳、md5、base64、AES,如何提供种能力。
- 断言问题:有些接口返回的结构体很复杂,如何灵活的做到断言。
seldom 适合个人接口自动化项目,它有以下优势:
- 可以写更少的代码
- 自动生成 HTML/XML 测试报告
- 支持参数化,减少重复的代码
- 支持生成随机数据
- 支持 har 文件转 case
- 支持数据库操作
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:
import seldom
import json
hna_ip = 'http://x.x.x.x:x'
p = '/x/x/'
def ReadJsonFile(filepath):
with open(filepath, 'r') as f:
content = f.read()
return json.loads(content)
class TestPreSale(seldom.TestCase):
def testpMultiEstimatePriceV2(self):
url = hna_ip + p
arg = ReadJsonFile('../leadscloud_test_data/pMultiEstimatePriceV2.json')
self.get(url, params=arg)
self.assertEqual(self.response['errno'], '0')
estimate_data = self.response['data']['estimate_data']
return estimate_data
主要简化点在,接口的返回数据的处理。当然,seldom 真正的优势在断言、日志和报告。
har to case:
- Charles > File > Export Session
- 导出类型选择为HTTP Archive (.har)
通过seldom -h2c 转为demo.py 脚本文件。
seldom -h2c .\demo.har
断言:
- seldom 可以针对JSON文件进行断言:assertJSON
import seldom
class TestAPI(seldom.TestCase):
def test_assert_json(self):
payload = {'name': 'tom', 'hobby': ['basketball', 'swim']}
self.get("http://httpbin.org/get", params=payload)
assert_json = {'args': {'hobby': ['swim', 'basketball'], 'name': 'tom'}}
self.assertJSON(assert_json)
if __name__ == '__main__':
seldom.main()
- seldom 中可以通过 path 进行断言:assertPath
import seldom
class TestAPI(seldom.TestCase):
def test_assert_path(self):
payload = {'name': 'tom', 'hobby': ['basketball', 'swim']}
self.get("http://httpbin.org/get", params=payload)
self.assertPath("name", "tom")
self.assertPath("args.hobby[0]", "basketball")
if __name__ == '__main__':
seldom.main()
- 断言数据的类型: assertSchema
import seldom
class TestAPI(seldom.TestCase):
def test_assert_schema(self):
payload = {"hobby": ["basketball", "swim"], "name": "tom", "age": "18"}
self.get("/get", params=payload)
schema = {
"type": "object",
"properties": {
"args": {
"type": "object",
"properties": {
"age": {"type": "string"},
"name": {"type": "string"},
"hobby": {
"type": "array",
"items": {
"type": "string"
},
}
}
}
},
}
self.assertSchema(schema)
if __name__ == '__main__':
seldom.main()
接口数据依赖:seldom 提供了self.response用于记录上个接口返回的结果,直接拿来用即可。
import seldom
class TestRespData(seldom.TestCase):
def test_data_dependency(self):
"""
Test for interface data dependencies
"""
headers = {"X-Account-Fullname": "bugmaster"}
self.get("/get", headers=headers)
self.assertStatusCode(200)
username = self.response["headers"]["X-Account-Fullname"]
self.post("/post", data={'username': username})
self.assertStatusCode(200)
数据驱动:同ddt
@data
@file_data
随机生成测试数据:
import seldom
from seldom import testdata
class TestAPI(seldom.TestCase):
def test_data(self):
phone = testdata.get_phone()
payload = {'phone': phone}
self.get("http://httpbin.org/get", params=payload)
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() |