HttpRunner是一款非常优秀的纯数据驱动接口测试框架,使用Yaml或JSON文件描述用例。
HttpRunner目前已经出到3.*版。由于HttpRunner2.0之后有较大改动。这里是使用1.5.6版本的教程。
安装
pip install httprunner==1.5.6 -i https://pypi.doubanio.com/simple/
基本使用
在HttpRunner中个人理解一个文件为一个测试套件,可以包含config配置和多个test用例,用例按顺序执行,支持用例依赖,一个用例使用上个用例的结果。
基本格式为:
- config: ... # 测试套件配置
- test: ... # 用例
- test: .... # 用例
编写test_httpbin.yaml,内容如下:
- config:
name: 测试套件
- test:
name: 用例1-GET请求
request:
url: https://httpbin.org/get
method: GET
- test:
name: 用例2-POST请求
request:
url: https://httpbin.org/post
method: POST
data:
a: 1
b: 2
每个test用例中的request方法的熟悉同requtets.request(method,url,**kwargs)方法的参数,支持params,data,files,json,headers,cookies,timeout等。
命令行运行:
hrun test_httpbin.yaml
运行后会在reports目录下生成已时间戳命名的html报告,命令行显示信息如下:
用例1-GET请求
INFO GET /get
INFO status_code: 200, response_time(ms): 1063.19 ms, response_length: 308 bytes
.
用例2-POST请求
INFO POST /post
INFO status_code: 200, response_time(ms): 532.91 ms, response_length: 489 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 1.600s
OK
INFO Start to render Html report ...
INFO Generated Html report: /Users/apple/Desktop/reports/1587382845.html
使用base_url
在用例config段可以通过base_url来配置测试接口服务域名,当url非已http开头时,会自动拼接上域名,修改后的test_httpbin.yaml内容如下。
- config:
name: 测试套件
request:
base_url: https://httpbin.org
- test:
name: 用例1-GET请求
request:
url: /get
method: GET
- test:
name: 用例2-POST请求
request:
url: /post
method: POST
data:
a: 1
b: 2
执行结果同上例。
注:1.5.6版本的base_url要配置在config/request中,2.0直接配置在config中
使用变量
config段可以通过variables来设置用户自定义变量,修改后的test_httpbin.yaml内容如下。
在步骤中通过$变量名引用变量值。
- config:
name: 测试套件
request:
base_url: https://httpbin.org
variables:
a: 1
b: 2
...
- test:
name: 用例2-POST请求
request:
url: /post
method: POST
data:
a: $a
b: $b
执行结果同上例。
请求默认配置config/request
在config/request段可以配置请求会话的默认熟悉,包括默认的params、headers、auth等等,示例如下。
- config:
name: 测试套件
request:
base_url: https://httpbin.org
headers:
token: abc123
...
查看报告详情可以看到每个请求中添加了请求头选项token。
变量提取variables
test中可以使用extract来提取并注册变量,之后的test中同样可以使用$变量名来。
...
- test:
name: 用例1-GET请求
request:
url: /get
method: GET
extract:
- u: content.url
- test:
name: 用例2-POST请求
request:
url: /post
method: POST
data:
a: $a
b: $b
u: $u
extract格式应为一个Array即Python中的列表格式,u是提取要注册的变量名,后面是提取表达式,content是requests的响应数据。
可用的结果变量如下:
- content: 响应JSON数据,字典类型
- headers: 响应头,字典类型
- cookies: 响应cookies, 字典类型
- status_code: 状态码,整型
- text: 响应文本
- reason: 状态码解释, 字符串类型
- elapsed: 响应时间,datetime.timedelta类型
- ok: 请求是否成功,布尔类型
- url: 响应的url,字符串类型
- request: 请求对象
除content外,可用的结果变量基本对应requests库Response对象的属性
响应数据content、响应头headers变量支持使用小数点向下级取属性或元素,Object类型使用.key取值,Array类型使用.索引取值。
假设请求响应为:
{"code": 0, "message": "成功", "data": [{"name": "kevin", "age": 12}]}
响应code和data中第一个元素的name属性的取法为:
content.code
content.data.0.name
使用断言validate
断言指期望结果与实际结果的对比,在测试用例中断言是必不可少的。
在test中使用断言的示例如下:
...
- test:
name: 步骤1-GET请求
request:
url: /get
method: GET
extract:
- u: content.url
validate:
- eq: [status_code, 200]
- {comparator: eq,check: content.url,expect: https://httpbin.org/get}
断言支持以下两种表述方式:
eq: [status_code, 200]
{comparator: eq,check: status_code,expect: 200}
comparator比较运算符eq代表等于,check校验字段,支持content、headers、status_code等所有的Response对象属性,expect为期望结果。
可用的比较运算符有:
各种数据类型通用:
- eq/ne/gt/lt/ge/le: 等于、不等于、大于、小于、大于等于、小于等于
- type_match:类型匹配
- str_eq: 转字符串后等于
- contains_by: 被包含,在列表或字符中
适用于字符串、列表等序列类型:
- len_eq/len_gt/len_lt/len_ge/len_lt:长度等于、长度大于、长度小于、长度大于等于、长度小于等于
- contains:包含
适用于字符串:
- regex_match:正则匹配
- startswith/endswith: 以特定字符串开头、以特定字符串结尾
使用skip跳过test用例
test中支持使用skip跳过用例,如:
- test:
name: 步骤3-未完成
skip: True
使用自定义函数
在test_httpbin.yaml同级新建文件debugtalk.py,编写自定义函数add,内容如下。
def add(a,b):
return a+b
yaml中使用${函数名(参数)}来引用自定义函数,示例如下。
- test:
name: 步骤2-POST请求
request:
url: /post
method: POST
data:
a: $a
b: $b
u: $u
c: ${add($a, $b)}
除了使用variables中的自定义变量外,还可以使用(request和)response。
(request是请求数据,字典格式,)response是ttprunner.response.ResponseObject对象,可以通过$response.resp_obj获取到原始的requests.Response对象。
使用setup_hooks和teardown_hooks
test中支持通过setup_hooks和teardown_hooks来指定测试前、后调用的debugtalk.py中的函数。
在debugtalk.py增加两个函数:
def setup(request):
print('setup')
print(request)
def teardown(response):
print('teardown')
print(response.resp_obj.text) # 原始请求文本
test_httpbin.yaml中添加用例4:
...
- test:
name: 用例4-使用setup和teardown
setup_hooks:
- ${setup($request)}
teardown_hooks:
- ${teardown($response)}
request:
url: /get
method: GET
运行后的部分结果如下:
用例4-使用setup和teardown
setup
{'headers': {'token': 'abc123'}, 'url': '/get', 'method': 'GET'}
INFO GET /get
INFO status_code: 200, response_time(ms): 1103.28 ms, response_length: 333 bytes
teardown
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"Token": "abc123",
"User-Agent": "python-requests/2.22.0",
"X-Amzn-Trace-Id": "Root=1-5e9e91c8-32862f3214a5a13ab5d43ced"
},
"origin": "111.194.126.253",
"url": "https://httpbin.org/get"
}
使用数据驱动parameters
test中支持使用parameters设置数据驱动,数据驱动支持使用变量和使用CSV文件两种。
使用变量
示例如下:
- test:
name: 用例5-数据驱动
parameters:
- a-b:
- [1,2]
- [3,4]
- [5,6]
request:
url: /get
method: GET
params:
a: $a
b: $b
a-b是参数化生成的变量,多个变量使用-连接,之下是每一组数据,request中同样通过$变量引用变量值。
实际运行时将根据数据数量参数多条用例。
使用CSV文件数据驱动
parameters中可以通过${P(csv文件)}来设置使用csv文件进行数据驱动。
在test_httpbin.yaml同级新建data.csv文件,内容如下。
a,b
1,2
2,4
3,5
注意:csv文件需要携带变量名行a,b
在test中使用parameters参数设置参数化,格式如下:
- test:
name: 用例6-CSV数据驱动
parameters:
- a-b: ${P(data.csv)}
request:
url: /get
method: GET
params:
a: $a
b: $b
运行时根据data.csv的数据产生多条用例。
使用环境变量
待补充
完整示例
test_httpbin.yaml内容
- config:
name: 测试套件
request:
base_url: https://httpbin.org
headers:
token: abc123
variables:
a: 1
b: 2
- test:
name: 用例1-GET请求
request:
url: /get
method: GET
extract:
- u: content.url
validate:
- eq: [status_code, 200]
- comparator: eq
check: content.url
expect: https://httpbin.org/get
- test:
name: 用例2-POST请求
request:
url: /post
method: POST
data:
a: $a
b: $b
u: $u
c: ${add($a, $b)}
- test:
name: 用例3-未完成
skip: True
- test:
name: 用例4-使用setup和teardown
setup_hooks:
- ${setup($request)}
teardown_hooks:
- ${teardown($response)}
request:
url: /get
method: GET
- test:
name: 用例5-数据驱动
parameters:
- a-b:
- [1,2]
- [3,4]
- [5,6]
request:
url: /get
method: GET
params:
a: $a
b: $b
- test:
name: 用例6-CSV数据驱动
parameters:
- a-b: ${P(data.csv)}
request:
url: /get
method: GET
params:
a: $a
b: $b
debugtalk.py内容
def add(a,b):
return a+b
def setup(request):
print('setup')
print(request)
def teardown(response):
print('teardown')
print(response.resp_obj.text) # 原始请求文本
data.csv内容
a,b
1,2
2,4
3,5