HttpRunner--变量与参数
HttpRunner–变量与参数
在测试用例中,很多时候我们需要对参数进行声明和引用,这就需要用到变量(variables)机制。httprunner中,可以用变量替换测试步骤中的某些值。
变量按照类型划分有:配置变量(config variables) 环境变量(env variables)和 参数变量(parameter
variables)
按照作用域划分有:测试步骤变量(step variables) 和 全局配置变量(config variables),步骤优先级大
于用例优先级
用例变量
在 HttpRunner 的测试用例中,约定通过 ${}
或 $
的形式来引用变量。
例如:$var
或 ${var}
大多数情况下,采用 $var
或 ${var}
这两种形式都是可以的。但如果在某些字段中存在部分引用变量的情况,例如 abc123def
中 123
需要引用变量,那么就只能使用 ${var}
的形式,即 abc${num}def
;如果使用 abc$numdef
的话,变量名称会被识别为 numdef
。
另一种需要说明的情况,如果在测试用例中本身就存在 $
符号,那么可以通过 $$
进行转义。
例如,测试用例中某个字段的原始内容为 $m
,那么为了避免将其解析为变量,则需要将其写为 $$m
使用命令hrun startproject demo
新增一个Httprunner项目,命名为demo
配置变量(config variables)
在 config
下声明的 variables
为测试用例全局变量,作用域为当前整个测试用例,在测试用例的所有地方都可以引用。
在testcases
目录下新增yaml文件
demo_login.yaml
config:
name: 登录测试用例
base_url: http://127.0.0.1:8080
variables: #定义变量
username: auto
password: sdfsdfsdf
teststeps:
- name: 用户名密码登录
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
body: #引用变量 也可以写成${变量名}
username: $username
password: $password
validate:
- check: status_code
assert: equals
expect: 200
msg: assert response status code
使用hrun
命令执行测试用例文件:hrun .\testcases\demo_login.yml
,用例执行成功,在日志文件中可以看到,传参内容为body : username=auto&password=sdfsdfsdf
如果变量需要从其他数据源读取,那么可以创建一个 debugtalk.py
文件,在其中定义函数返回键值对变量
debugtalk.py
def login_variables():
return {'user':'auto','pwd':'sdfsdfsdf',"code":0}
demo_login.yaml
config:
name: 登录测试用例
verify: false
base_url: http://127.0.0.1:8080
variables: ${login_variables()}
teststeps:
- name: 用户名密码登录
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data: #引用变量 也可以写成${变量名}
username: ${user}
password: ${pwd}
validate:
- eq:
- status_code
- 200
- eq:
- body.retcode
- $code
使用hrun
命令执行测试用例文件:hrun .\testcases\demo_login.yml
,用例执行成功
在日志文件中可以看到,传参内容为body : username=auto&password=sdfsdfsdf
,参数是通过获取login_variables
函数进行获取;断言内容均为通过assert status_code equal 200(int) ==> pass
、assert body.retcode equal 0(int) ==> pass
测试步骤变量 (step variables)
在单个测试步骤(teststep
)下声明的 variables
是测试步骤局部变量,作用域仅限当前步骤。
各个测试步骤的变量相互独立,互不影响
demo_login.yaml
config:
name: "登录测试用例"
variables: ${login_variables()}
base_url: "http://127.0.0.1:8080"
teststeps:
-
name: "用户名密码登录"
variables:
user: auto
psw: sdfsdfsdf666
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data:
username: ${user} #引用变量 也可以写成${变量名}
password: ${psw}
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", $code]
如果步骤中的变量名和用例变量名相同,步骤变量优先级高于用例变量。 所以,data
中username
和password
的取值为步骤变量中的auto
和sdfsdfsdf666
,而不是 debugtalk.py
文件定义函数返回键值对变量
注意:步骤变量不支持函数返回值模式 即不支持 variables: ${login_variables()}
这种形式
环境变量(env variables)
对于一些环境数据,平时不方便卸载用例中进行维护的,我们可以放在环境变量文件中,方式是保存在项
目根目录下的.env
文件(如果文件没有就创建,文件名就是 .env
)
.env
user=auto
psw=sdfsdfsdf
使用环境变量,通过${ENV(user)}
和${ENV(psw)}
将项
目根目录下的.env
文件中user
和psw
的值,赋予在config
中定义的变量username
和password
,然后在测试步骤中引用变量
demo_login.yaml
config:
name: "登录测试用例"
variables:
username: ${ENV(user)} #定义变量
password: ${ENV(psw)}
base_url: "http://127.0.0.1:8080"
teststeps:
-
name: "用户名密码登录"
variables:
user: auto
psw: sdfsdfsdf666
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data:
username: $username #引用变量 也可以写成${变量名}
password: $password
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", 0]
参数变量(parameter variables)
参数变量的用途就是作为数据驱动被使用,在 config
下声明的 parameters
为测试用例的驱动参数;它的作用域也是覆盖整个测试用例,在测试用例的所有地方都可以引用。
独立参数 & 直接指定参数列表
demo_login.yaml
config:
name: "登录测试用例"
base_url: "http://127.0.0.1:8080"
parameters:
username:
- auto
- auto2
password:
- sdfsdfsdf
- sdfsdfsdf2
- sdfsdfsdf3
teststeps:
-
name: "用户名密码登录"
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data:
username: $username #引用变量 也可以写成${变量名}
password: $password
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", 0]
实际的参数数量等于 username
的参数个数乘以password
参数的个数,即笛卡尔积,执行了6个场景,logs目录下生成了6个日志文件
关联参数 & 直接指定参数列表
在有些场景的接口,需要用到登录后的cookie信息,不同接口参数之间存在关联,应该以关联方式传递参数
demo_login.yaml
config:
name: "测试用例"
base_url: "http://127.0.0.1:8080"
parameters:
username-password:
- ['auto','sdfsdfsdf']
- ['auto2','sdfsdfsdf2']
teststeps:
-
name: "用户名密码登录"
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data:
username: $username #引用变量 也可以写成${变量名}
password: $password
extract: #提取当前步骤变量
cookie: cookies.sessionid
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", 0]
-
name: "查询课程"
request:
method: GET
url: /api/mgr/sq_mgr/
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
params:
action: list_course
pagenum: 1
pagesize: 20
extract: #提取当前步骤变量
id: body.retlist[0].id
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", 0]
这里只执行了2个场景,通过两个不同的账号,获取登录后的cookie信息,从而获取不同的课程信息
关联参数 & 引用自定义函数
对于没有现成参数列表,或者需要更灵活的方式动态生成参数的情况,可以通过在 debugtalk.py 中自定义函数生成参数列表,并在 YAML/JSON 引用自定义函数的方式。
编写获取参数的函数,如:
debugtalk.py
def get_login_data():
return [
{'username':'auto','password':'sdfsdfsdf',"code":0},
{'username': 'auto', 'password': 'sdfsdfsdf1', "code": 1},
{'username': 'auto1', 'password': 'sdfsdfsdf', "code": 1},
]
返回参数的格式为 [{key:value},{key2:value}...]
参数变量(parameter variables) 部分修改为,参数名1-参数名2-参数名3: ${get_login_datat()}
, 可以理
解为${函数返回值}
demo_login.yaml
config:
name: "测试用例"
base_url: "http://127.0.0.1:8080"
parameters:
username-password-code: ${get_login_data()}
teststeps:
-
name: "用户名密码登录"
request:
method: POST
url: /api/mgr/loginReq
headers:
Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"
cookies:
csrftoken: 1esSz9MFIZRpjAmZrvVLrL9NdiXbNpXU
data:
username: $username #引用变量 也可以写成${变量名}
password: $password
extract: #提取当前步骤变量
cookie: cookies.sessionid
validate:
- eq: ["status_code", 200]
- eq: ["body.retcode", $code]