HttpRunner
is a simple & elegant, yet powerful HTTP(S) testing framework.
本文主要记录特定版本: v==3.0.1 的相关使用心得。
版本选择
当前最新版本是 3.1.4 ,该版本作者推荐使用 .py 文件进行脚本编写和维护,主要是为了复用 IDE 的链式调用功能,
不过个人并不喜欢,同时新版本在兼容旧版本脚本方面存在一定问题,迁移工作量较大。
因此个人还是推荐使用 3.0.1 版本,这个版本和 2.0.x 版本使用很接近,因此我们在使用中可以看一下 2.0.x 的
文档。
3.0.x 的官方文档在 这里。
同时,这里提供一份他人翻译的 中文文档,
个人觉得还是写的挺好,不仅仅是翻译。
安装
1
|
$pip install httprunner==3.0.1 -i https://mirrors.aliyun.com/pypi/simple/
|
鉴于国内的网络环境,因此我们使用一个 -i 参数来指定 pypi 源。
创建一个 demo
使用如下命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$httprunner --startproject demo
# 官方文档startproject前是不需要加--的
# 但是-h参数表示需要加,不加也的确会报错
httprunner.utils:create_scaffold:359 - Start to create new project: demo
httprunner.utils:create_folder:365 - created folder: demo
httprunner.utils:create_folder:365 - created folder: demo\api
httprunner.utils:create_folder:365 - created folder: demo\testcases
httprunner.utils:create_folder:365 - created folder: demo\testsuites
httprunner.utils:create_folder:365 - created folder: demo\reports
httprunner.utils:create_file:371 - created file: demo\api\demo_api.yml
httprunner.utils:create_file:371 - created file: demo\testcases\demo_testcase.yml
httprunner.utils:create_file:371 - created file: demo\testsuites\demo_testsuite.yml
httprunner.utils:create_file:371 - created file: demo\debugtalk.py
httprunner.utils:create_file:371 - created file: demo\.env
httprunner.utils:create_file:371 - created file: demo\.gitignore
|
生成的文件目录结构:
从上面的目录结构能够很清楚看出来,这个版本的 HttpRunner
分了 3 层:api
层、testcase
层、testsuite
层。
ps.最新版本推荐分两层,个人觉得也可以接受
因为设定了 testcase 里可以调 testcase
感兴趣可以建一个最新版的 demo 看下
mock 一个接口用于测试
接口文档:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
host: http://127.0.0.1:8000
method: post
url: /insert
请求参数:
{
"name": "string",
"age": 0,
"address": "string",
"salary": 0
}
响应:
{
"success": true,
"msg": "此人名字叫做:{name},十年后此人年龄:{age+10}"
}
|
编写脚本
根据上面的接口文档,我们可以写出如下脚本
api
层:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$cat api/demo_api.yml
name: demo api
variables:
body:
name: $name
age: $age
address: $address
salary: $salary
request:
url: /insert
method: POST
headers:
Content-Type: "application/json"
json: $body
validate:
- eq: ["status_code", 200]
|
testcase
层:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
config:
name: "demo testcase"
base_url: "http://127.0.0.1:8000"
teststeps:
-
name: demo testcase
api: api/demo_api.yml
variables:
name: noel
age: 15
address: beijing
salary: 7777
extract:
- msg: content.msg
validate:
- eq: ["status_code", 200]
|
testsuite
层:
1
2
3
4
5
6
7
8
|
config:
name: "demo testsuite"
base_url: "http://127.0.0.1:5000"
testcases:
-
name: call demo with api data
testcase: testcases/demo_testcase.yml
|
执行一下脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$hrun testsuites/demo_testsuite.yml
2021-04-28 23:16:37.317 | INFO | httprunner.api:run:334 - HttpRunner version: 3.0.1
2021-04-28 23:16:37.318 | INFO | httprunner.loader.load:load_dot_env_file:172 - Loading environment variables from /Users/jiawang/PycharmProjects/oldhttprunner/demo/.env
2021-04-28 23:16:37.343 | INFO | httprunner.api:_run_suite:146 - Start to run testcase: call demo with api data
2021-04-28 23:16:37.343 | INFO | httprunner.report.html.result:startTest:30 - demo testcase
2021-04-28 23:16:37.344 | INFO | httprunner.runner:_run_test:242 - POST http://127.0.0.1:8000/insert
2021-04-28 23:16:37.350 | INFO | httprunner.client:request:221 - status_code: 200, response_time(ms): 6.15 ms, response_length: 79 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
2021-04-28 23:16:37.363 | INFO | httprunner.report.html.gen_report:gen_html_report:34 - Start to render Html report ...
2021-04-28 23:16:37.396 | INFO | httprunner.report.html.gen_report:gen_html_report:61 - Generated Html report: /Users/jiawang/PycharmProjects/oldhttprunner/demo/reports/20210428T151637.343656.html
|
贴一下测试报告里的请求与响应
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
Request:
url http://127.0.0.1:8000/insert
method POST
headers
{
"User-Agent": "python-requests/2.25.1",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
"Content-Type": "application/json",
"HRUN-Request-ID": "4d2a31e2-481d-425d-8718-540aa8b342bb",
"Content-Length": "65"
}
body
{
"name": "noel",
"age": 15,
"address": "beijing",
"salary": 7777
}
Response:
ok True
url http://127.0.0.1:8000/insert
status_code 200
reason OK
cookies {}
encoding utf-8
headers
{
"date": "Wed, 28 Apr 2021 15:16:36 GMT",
"server": "uvicorn",
"content-length": "79",
"content-type": "application/json"
}
content_type application/json
body
{
"success": true,
"msg": "此人名字叫做:noel,十年后此人年龄:25"
}
|
变量权重(重点)
在每一层都可以定义变量,但是各层的权重是不同的。api
层拥有最高的权重,
其次是 testcase
,最后是testsuite
。
即如果你已经在 api 层把一个常量赋值给了一个变量,
那么即使你在 testcase
或者 testsuite
层再去给这个变量赋值,
也不会生效。
我们可以看一下上面的脚本,我在 testcase
和 testsuite
中都有对 base_url
进行赋值,
但是最后测试报告中的 base_url
是 testcase
里的。
官方关于变量权重的说明,在
这里
数据驱动
HttpRunner
中建议使用的数据文件是 CSV
以上面 mock
的接口为例
我们在 data.csv
文件中写入如下数据:
1
2
3
|
name,age,address,salary
noel,15,1,5000
张三,25,北京,8000
|
那么我们的脚本就需要做如下变动:
1.api
层不需要做改动
2.testcase
层做如下改动:
去除在这一层对变量(csv文件中包含了的变量)的赋值
1
2
3
4
5
6
7
8
9
10
11
12
|
config:
name: "demo testcase"
base_url: "http://127.0.0.1:8000"
teststeps:
-
name: demo testcase
api: api/demo_api.yml
extract:
- msg: content.msg
validate:
- eq: ["status_code", 200]
|
3.testsuite
层做如下改动:
新增 parameters
参数,使用 -
拼接 csv
文件中的第一行数据
1
2
3
4
5
6
7
8
9
10
|
config:
name: "demo testsuite"
base_url: "http://127.0.0.1:5000"
testcases:
-
name: call demo with api data
testcase: testcases/demo_testcase.yml
parameters:
name-age-address-salary: ${P(data/data.csv)}
|
大工告成,再次执行上面的命令,此时就会跑两次这个接口
自定义函数
因为 httprunner 规范了太多,以及使用 yaml 文件来维护用例,
使得我们的自由度降低很多,为了弥补这一缺点,
作者留下了 debugtalk.py
文件,方便我们自定义参数
我们以一个随机生成名字的函数举例说明如何自定义函数以及调用
首先编辑 debugtalk.py
文件
1
2
3
4
5
6
7
8
9
10
|
import random
def get_name():
"""
随机生成一个 name
"""
data = []
for i in range(6):
data.append(random.choice('1234567890qwertyuiopasdfghjklzxcvbnm'))
return ''.join(data)
|
调用时建议写在 testcase
层,或者 csv
文件中,二选一
写在 testcase
层:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
config:
name: "demo testcase"
base_url: "http://127.0.0.1:8000"
teststeps:
-
name: demo testcase
api: api/demo_api.yml
variables:
name: ${get_name()}
extract:
- msg: content.msg
validate:
- eq: ["status_code", 200]
|
写在 csv
文件中
1
2
3
|
name,age,address,salary
${get_name()},15,1,5000
${get_name()},25,北京,8000
|
全文完~