文章目录
一、HttpRunner 2.x项目工程结构
1、版本选择
安装2.5.7版本,3.x版本暂时还不稳定,有很多bug,所以先用2.x版本
pip install httprunner==2.5.7
2、运行命令
安装完成后,会自带httprunner、hrun命令,用于运行用例、管理操作;
生成项目目录:
hrun --startproject HttpRunnerDemo
运行用例:
hrun filepath/testcase.yml
3、项目结构
- api目录:用于存放接口的最小单元(正向用例)
- reports目录:用于存放测试报告
- testcases目录:用于处理接口复杂的执行逻辑;处理接口依赖
- testsuites目录:用户批量执行用例,可以实现数据驱动测试
- .env文件:用于存放全局环境变量
- debugtalk.py文件:用于定义python函数,处理动态参数
二、yaml文件格式简要说明
httprunner框架一般只需要维护yaml文件即可,简单介绍下yaml文件的基本规范和写法
- yaml配置文件的后缀为.yml或者.yaml
- yaml中使用#作为注释,注释只能在某一行的前后,不能与key\value在同一行
- yaml中有两种结构,一种是key: value,value与冒号之间必须有空格,另一种是 - key: value,“-”为列表结构
- 同一级条目前缩进必须一致;(一般都是2个空格)
- yaml中如果value使用引号(单引号或者双引号),那么该value为字符串类型
- 如果value中只要有字母,哪怕没有添加引号,一般也会识别为字符串类型(false、true、on、off、null除外)
- value中为纯数字或者小数,会被识别为int或float类型
三、api
api目录中存放接口yaml文件,具体解释如下:
# name指定当前用例名称
name: "登录login接口"
# 设置基本路径,运行时会自动与下面的url拼接在一起
base_url: "http://127.0.0.1:8000"
# variables设置变量
# a.指定当前用例的局部变量
# b.可以在变量定义的下方任意地方调用
# c.使用$变量进行调用
# d.作用域为当前yaml文件,变量定义的下方,不能跨yaml文件进行调用
variables:
username: value1
password: value2
# request定义当前接口的配置信息,请求参数名称与requests模块完全兼容
request:
# 指定当前接口的url地址,如果在全局指定了base_url,那么会自动拼接base_url
url: "/user/login/"
# method指定当前接口的请求方法名称,请求方法有:GET、POST、PUT、DELETE、PATCH,不区分大小写
method: POST
# 指定请求头参数
headers:
Content-Type: "application/json"
# 可以在项目根路径下的debugtalk.py文件中,定义python函数或者类,用于处理动态参数
User-Agent: "${random_generate_uagent()}"
# 指定请求体为json格式的参数
json:
key: $var2
# 如果指定x-www-form-urlencoded参数就用data
# data:
# username: "$username"
# password: "$password"
# validate指定断言
validate:
# eq为断言类型,断言实际值与期望值是否相等
# 完整形式为"equals",也可以使用"eq", "equals", "==", "is"
# 除eq外还有其他断言类型,如:lt、le、gt、ge、ne等等,contains:判断实际值是否包含期望值,contained_by:判断实际值是否包含在期望值中
- eq: ["status_code", 200]
# 方括号中,第一个参数为实际值,第二个参数为期望值
- contains: ["json", "username"]
# 提取返回参数体信息进行断言,使用content加上“.”运算加上key,就能获取到相应值
- lt: ["json.user_id", 2]
# 断言方式的完整形式
# {"check": "实际值", "comparator": "断言类型", "expect": 期望值}
# - {"check": "json.user_id", "comparator": "lt", "expect": 2}
运行该yml文件
hrun api/demo.yml
四、testcases
举例:先登录,然后提取token,再获取项目列表数据
# 指定用例的全局配置信息,如果有就写,如果没有可不写
config:
name: "demo testcase"
# 定义当前用例的执行逻辑,从前往后依次执行,可以实现接口依赖,也可以实现数据驱动测试
teststeps:
-
name: "先登录"
# 指定导入api文件夹下的接口的api最小执行单元
api: "api/login_api.yml"
# 从相应结果中提取数据,并设置变量
# 设置的变量,可以在当前yaml用例文件下方任意地方调用
extract:
- TOKEN: "content.token"
-
name: "获取项目列表数据接口"
api: "api/projects_list_api.yml"
五、testsuites
# 指定测试套件中的全局配置信息
config:
name: "测试条件"
# 指定套件中的用例
testcases:
-
name: "登录接口测试"
# 注意:此处只能引用 testcase下的yml文件,不能引用api下的
testcase: "testcases/login_testcase.yml"
-
name: "获取项目列表接口"
testcase: "testcases/project_list_testcase.yml"
六、ENV变量定义及引用
在.env文件中定义经常引用的变量,然后通过${ENV(BASE_URL)}来引用
USERNAME=test
PASSWORD=123456
BASE_URL=http://127.0.0.1:8000
七、数据驱动
1)第一种方法:直接写在parameters内,固定写法,用-分隔变量,每个列表为一条用例,顺序对应变量名
2)第二种方法:通过调用函数方法, ${get_accounts()},函数get_accounts()需要写在debugtalk.py中
3)第三种方法:通过csv文件导入 ,括号内写csv的相对路径,${P(data/data.csv)}
代码示例如下:
# 第一种方法
# 固定写法,用-分隔变量
# parameters:
# - title-username-password-status_code-msg:
# - ["正常登录", "", "123456", 200, "token"]
# - ["用户名为空", "", "123456", 400, "username"]
# - ["密码为空", "keyou1", "", 400, "password"]
# - ["密码不正确", "keyou1", "1234567", 400, "non_field_errors"]
# 第二种方法,get_accounts()为debugtalk.py中的方法
parameters:
- title-username-password-status_code-msg: ${get_accounts()}
# 第三种方法,csv文件导入数据
parameters:
- title-username-password-status_code-msg: ${P(data/data.csv)}
#-------分割线-------------------------------------------------------------
# csv文件内容:
title,username,password,status_code,msg
正常登录,keyou1,123456,200,token
密码错误,keyou1,123457,400,non_field_errors
账号错误,keyou1111,123456,400,non_field_errors
用户名为空,,123456,400,username
密码为空,keyou1,,400,password
# debugtalk.py中get_accounts()
def get_accounts():
accounts = [
{"title": "正常登录", "username": "keyou1", "password": "123456",
"status_code": 200, "msg": "token"},
{"title": "密码错误", "username": "keyou1", "password": "123457",
"status_code": 400, "msg": "non_field_errors"},
{"title": "账号错误", "username": "keyou1111", "password": "123456",
"status_code": 400, "msg": "non_field_errors"},
{"title": "用户名为空", "username": "", "password": "123456",
"status_code": 400, "msg": "username"},
{"title": "密码为空", "username": "keyou1", "password": "",
"status_code": 400, "msg": "password"},
]
return accounts
八、debugtalks
Httprunner框架中,只能使用yaml文件进行用例描述,为了实现复杂的逻辑或者操作,框架引入了debugtalk.py辅助函数来进行一些复杂操作
- 使用步骤:
- 新建debugtalk.py,在这个py文件中编写你要实现的逻辑代码函数(要与yaml文件同目录下)
- 在yaml中引用对应的函数;
代码实例:
debugtalk.py中定义获取token的方法
import requests
import json
#获取token
def get_token():
headers = {
'Content-Type': 'application/json',
}
datas = {'sign': '9c0c7e51c91ae963c833a4ccbab8d683c4a90c98'}
url = "http://127.0.0.1:5000/api/get-token"
response = requests.post(url=url, json=datas, headers=headers)
return response.json()["token"]
${get_token()} #引用方法
- test:
name: /api/project/
request:
headers:
Content-Type: application/json
# 引用方法
token: ${get_token()}
json:
name: $username
password: $password
method: POST
url: /api/project/
validate:
- eq: [status_code, 201]
九、钩子函数
setup_hooks和teardown_hooks相当于pytest中的setup和teardown
一般来说最常用的用法就是在执行用例前或者执行用例后,处理数据或者清理数据,
具体代码实例如下:
# debugtalk.py代码
def init_data():
print("初始化数据")
def clear_data():
print("清理数据")
# yml文件中的引用
- config:
name: 项目2之登录接口测试
request:
base_url: http://localhost:8000
- test:
extract:
- token: content.token
name: 项目2之登录接口测试
request:
json:
username: "test"
password: "1234"
method: POST
url: /user/login/
setup_hooks:
- ${init_data()}
teardown_hooks:
- ${clear_data()}
validate:
- check: status_code
comparator: equals
expected: 200