介绍
testtp 是一个requests的拓展,默认增加了参数渲染,上下文结果记录,response结果校验功能。可以更简单的进行http api测试的编写和维护。
目录
为什么需要testtp
1. 一个典型的接口测试场景
一个代码样例
import requests
import time
import random
# 测试创建一个item,然后修改
def test_demo():
data = {
"key": "constant_value",
"name": "jason borne",
"timestamp": time.time() # 1.动态数据
}
# 创建
resp1 = requests.post(url="http://www.url1/item", json=data)
assert resp1.json()['code'] == 1
item_id = resp1.json()['data']['id'] # 2.上下文数据
# 修改
data2 = {
"id": item_id,
"name": "bruce wayne"
}
resp2 = requests.put(url="http://www.url1/item", json=data)
assert resp1.json()['code'] == 1
assert resp2.json()['data']['name'] == 'bruce wayne' # 3.结果解析和校验
2. 遇到的痛点
- 请求中的动态数据需要编码,例如时间戳,随机id等。不利于测试数据分离。
- 上下文数据需要解析和保存。
- 结果的校验需要解析出结果,然后assert校验,校验字段多的话代码冗长,复杂的情况还要增加if-else判断。
3. 期望的解决方式
- 测试数据可以模板化,运行时自动生成数据。配置化,比如不同的环境或不同的用户,加载不同的值。
- 更方便的保存上下文的数据。
- 更简单的数据校验,灵活。
4. testtp 主要功能
4.1 三板斧之一【render】(数据渲染)
思路:请求接收一个数据模板,发送请求时渲染成真正的数据,一份模板使用不同的配置,不同时间执行发出的多次请求数据是不同的。来解决动态参数的硬编码。
实现:数据模板中要标识出哪些是变量,哪些是函数。
请求Session中可以保存变量的值和对应的函数,从而在运行时将模板中的变量的值和函数的运算结果加载到数据模板中,形成真正的请求数据。
规则 | 标识符 | 结果 | 实现方式 |
---|---|---|---|
变量替换 | "{{ value }}"③ | 变量value的值 | cache① |
函数生成 | "{% func(args) %}" | 函数func运行的结果 | register_render② |
①每个Session有个cache对象,渲染时将value替换成cache中的对应数据
②可通过Session的 register_render方法将函数注册,渲染时即可调用
③用字符串规则来标识函数和变量,使得测试数据为json格式,方便数据的存储于外部文件或数据库
import random
from testtp import Session
s = Session()
# 变量
s.cache = {"name": "benshan"}
# 自定义函数
def rand_id():
returen random.randint(10, 199)
s.register_render = {"rand_id": rand_id} # 将函数注册到session
# 数据模板
template = {
"id": "{% rand_id() %}",
"name": "{{ name }}",
"key" : "value",
"timestamp": "{% int(time.time()) %}"
}
# 直接将模板传递给发送请求, 实际请求中的数据会被渲染成
s.post(url, json=template)
{
"id": 26,
"name": "benshan",
"key" : "value",
"timestamp": 1611986441
}
# 多次执行,生成不同的数据
s.post(url, json=template)
{
"id": 65,
"name": "benshan",
"key" : "value",
"timestamp": 1611986709
}
通过将函数直接存到数据模板,
运行时加载不同的配置信息到session的cache,可以实现测试数据的配置话;
提高了测试数据的健壮性
4.2 三板斧之二 【stash】 (上下文数据存储)
stash方法通过上次请求返回结果的jsonpath,定位到目标数据,将其存储到session的缓存中,供后续请求使用.
最开始示例中的请求可以改写
s =Session()
s.post(url="http://www.url1/item", json=data)
# 将返回的response.json()['data']['id']字段的值存到缓存cache中,key为'item_id'
s.stash(json_query='data.id', 'item_id')
# 后续请求可直接使用变量名item_id作为参数调用
s.put(url="http://www.url1/item", json={"id": "{{ item_id }}", "name": "other"})
4.3 三板斧之三【validate】(数据校验)
validate函数,接受一个schema模板来进行数据校验,减少assert的数据解析和校验步骤。
同template一样,schema一样支持函数和变量的替换。样例:
def is_url(s):
return s.startswith('http')
s = Session()
s.get('http://httpbin.org/get')
scm = {
"args": {},
"headers": {
"Accept": "{% str %}", # 校验 此处的值为字符串
"Accept-Encoding": "{% str %}",
"Host": "httpbin.org", # 校验此处的值等于 "httpbin.org"
"User-Agent": "{% str %}",
"X-Amzn-Trace-Id": "{% str %}"
},
"origin": "{% str %}",
"url": "{% is_url %}" # 自定义函数调用,校验运行 is_url(此处数据) == True
}
s.validate(scm)
5.使用testtp重新实现的代码样例
from testtp import Sesson
datas = [
{
"key": "constant_value",
"name": "jason borne",
"timestamp": "{% time.time() %}"
},
{
"name": "bruce wayne",
"id": "{{ item_id }}"
}
]
schema = {
"code": 1,
"data": {"name": "bruce wayne"}
}
def test_demo(datas, chema):
s = Session()
# 1.创建item
s.post(url="http://www.url1/item", json=datas[0])
# 2.缓存id
s.stash(json_query='data.id', 'item_id')
# 3.修改item
s.put(url="http://www.url1/item", json=datas[1])
# 4.结果解析和校验
s.validate(schema)
可见代码变得更加清晰,测试数据也更简洁。
安装
pip install testtp