seldom 2.0让接口自动化测试更简单

seldom 2.0让接口自动化测试更简单,第1张

seldom 2.0 让接口自动化测试更简单 前言

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是如何来做接口自动化的:

import unittest
import requests class TestAPI(unittest.TestCase): def test_get_method(self):
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
self.assertEqual(r.status_code, 200) if __name__ == '__main__':
unittest.main()

这其实已经非常简洁了。


同样的用例,用seldom实现。


# test_req.py
import seldom class TestAPI(seldom.TestCase): def test_get_method(self):
payload = {'key1': 'value1', 'key2': 'value2'}
self.get("http://httpbin.org/get", params=payload)
self.assertStatusCode(200) if __name__ == '__main__':
seldom.main()

主要简化点在,接口的返回数据的处理。


当然,seldom真正的优势在断言、日志和报告。


har to case

对于不熟悉 Requests 库的人来说,通过Seldom来写接口测试用例还是会有一点难度。


于是,seldom提供了har 文件转 case 的命令。


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


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

选择导出的文件格式。


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


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


> seldom -h2c .\demo.har
.\demo.py
2021-06-14 18:05:50 [INFO] Start to generate testcase.
2021-06-14 18:05:50 [INFO] created file: D:\.\demo.py

demo.py 文件。


import seldom

class TestRequest(seldom.TestCase):

    def start(self):
self.url = "http://httpbin.org/post" def test_case(self):
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"}
cookies = {"lang": "zh"}
self.post(self.url, json={"key1": "value1", "key2": "value2"}, headers=headers, cookies=cookies)
self.assertStatusCode(200) if __name__ == '__main__':
seldom.main()
运行测试

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


> python .\test_req.py
2021-04-29 18:19:39 [INFO] A run the test in debug mode without generating HTML report!
2021-04-29 18:19:39 [INFO]
__ __
________ / /___/ /___ ____ ____
/ ___/ _ \/ / __ / __ \/ __ ` ___/
(__ ) __/ / /_/ / /_/ / / / / / /
/____/\___/_/\__,_/\____/_/ /_/ /_/
-----------------------------------------
@itest.info test_get_method (test_req.TestAPI) ...
----------- Request ---------------
url: http://httpbin.org/get method: GET
----------- Response ️ -------------
type: json
{'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'}
ok ----------------------------------------------------------------------
Ran 1 test in 0.619s OK

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


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

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


assertJSON

接口返回结果如下:

{
"args": {
"hobby": [
"basketball",
"swim"
],
"name": "tom"
}
}

我的目标是断言namehobby 部分的内容。


seldom可以针对JSON文件进行断言。


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)

运行日志

test_get_method (test_req.TestAPI) ...
----------- Request ---------------
url: http://httpbin.org/get method: GET
----------- Response ️ -------------
type: json
{'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'}
Assert data has not key: headers
Assert data has not key: origin
Assert data has not key: url
ok ----------------------------------------------------------------------
Ran 1 test in 1.305s OK

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


assertPath

接口返回数据如下:

{
"args": {
"hobby":
["basketball", "swim"],
"name": "tom"
}
}

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

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")

assertSchema

有时并不关心数据本身是什么,而是需要断言数据的类型。


assertSchema 是基于 jsonschema 实现的断言方法。


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

接口返回数据如下:

{
"args": {
"hobby":
["basketball", "swim"],
"name": "tom",
"age": "18"
}
}

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

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)

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


接口数据依赖

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


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)

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


数据驱动

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


@data

import seldom
from seldom import data class TestDDT(seldom.TestCase): @data([
("key1", 'value1'),
("key2", 'value2'),
("key3", 'value3')
])
def test_data(self, key, value):
"""
Data-Driver Tests
"""
payload = {key: value}
self.post("/post", data=payload)
self.assertStatusCode(200)
self.assertEqual(self.response["form"][key], value)

@file_data

创建data.json数据文件

{
"login": [
["admin", "admin123"],
["guest", "guest123"]
]
}

通过file_data实现数据驱动。


import seldom
from seldom import file_data class TestDDT(seldom.TestCase): @file_data("data.json", key="login")
def test_data(self, username, password):
"""
Data-Driver Tests
"""
payload = {username: password}
self.post("http://httpbin.org/post", data=payload)
self.assertStatusCode(200)
self.assertEqual(self.response["form"][username], password)

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

随机生成测试数据

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


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() 连接数据库

连接sqlit3数据库

from seldom.db_operation import SQLiteDB

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

连接MySQL数据库(需要)

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

db = MySQLDB(host="127.0.0.1",
port="3306",
user="root",
password="123",
database="db_name")
*** 作方法
  • delete_data

删除表数据。


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

插入一条数据。


data = {'id': 1, 'username': 'admin', 'password': "123"},
db.insert_data(table="user", data=data)
  • select_data

查询表数据。


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

更新表数据。


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

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



datas = {
'api_event': [
{'id': 1, 'name': '红米Pro发布会'},
{'id': 2, 'name': '可参加人数为0'},
{'id': 3, 'name': '当前状态为0关闭'},
{'id': 4, 'name': '发布会已结束'},
{'id': 5, 'name': '小米5发布会'},
],
'api_guest': [
{'id': 1, 'real_name': 'alen'},
{'id': 2, 'real_name': 'has sign'},
{'id': 3, 'real_name': 'tom'},
]
} db.init_table(datas)
  • close

关闭数据库连接。


db.close()

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/589238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存