前言
在 HttpRunner 中,支持变量声明(variables)和引用($var)的机制。
在 config 和 step 中均可以通过 variables 关键字定义变量,然后在测试步骤中可以通过 $变量名称
的方式引用变量。
区别在于
- 在 config 中定义的变量为全局的,整个测试用例(testcase)的所有地方均可以引用;
- 在 step 中定义的变量作用域仅局限于当前测试步骤(teststep)
环境:httprunner==3.1.4
step 局部变量
在登录案例中,账号和密码是写死的,一般写用例的时候,我们最好把这种可能会变的参数单独写个变量。做到测试数据和代码的分离,以便后续维护。
如果我们在步骤(step)下声明的变量,作用域只在当前步骤(step)下有效。声明变量用 variables
,变量和对应值用键值对,如
teststeps:
-
name: step login
variables:
user: test
psw: "123456"
引用 user 和 psw 变量用 $user
, $psw
, 完整的 login_var.yml 脚本如下
config:
name: login case
base_url: http://127.0.0.1:8000
export:
- token
teststeps:
-
name: step login
variables:
user: test
psw: "123456"
request:
url: /api/v1/login
method: POST
json:
username: $user
password: $psw
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [content.code, 0]
- eq: [content.msg, login success!]
- len_eq: [content.token, 40]
pytest 脚本设置变量用with_variables()
方法
Step(
RunRequest("step login")
.with_variables(**{"user": "test", "psw": "123456"})
完整的 pytest 脚本 login_var_test.py
# NOTE: Generated By HttpRunner v3.1.4
# FROM: login_var.yml
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseLoginVar(HttpRunner):
config = (
Config("login case").base_url("http://127.0.0.1:8000").export(*["token"])
)
teststeps = [
Step(
RunRequest("step login")
.with_variables(**{"user": "test", "psw": "123456"})
.post("/api/v1/login")
.with_json({"username": "$user", "password": "$psw"})
.extract()
.with_jmespath("body.token", "token")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.code", 0)
.assert_equal("body.msg", "login success!")
.assert_length_equal("body.token", 40)
),
]
if __name__ == "__main__":
TestCaseLoginVar().test_start()
config 全局变量
在config下声明变量(variables)是全局变量,这样就在整个.yml文件生效了,yml格式如下
config:
name: logincase
variables:
user: test
psw: "123456"
teststeps中,有多个 step 都需要引用账号 user, 于是可以直接引用 config 的变量$user
config:
name: logincase
variables:
user: test
psw: "123456"
base_url: http://127.0.0.1:8000
export:
- token
teststeps:
-
name: step1 login
request:
url: /api/v1/login/
method: POST
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
json:
username: $user
password: $psw
extract:
token: content.token # 提取token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.msg, login success!]
- eq: [content.code, 0]
-
name: step2 get user info
request:
url: /api/v1/userinfo/
method: GET
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
Authorization: Token $token # 引用token
validate:
- eq: [content.code, 0]
- eq: [content.data.0.name, $user]
pytest完整脚本
# NOTE: Generated By HttpRunner v3.1.4
# FROM: userinfo_var.yml
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseUserinfoVar(HttpRunner):
config = (
Config("logincase")
.variables(**{"user": "test", "psw": "123456"})
.base_url("http://127.0.0.1:8000")
.export(*["token"])
)
teststeps = [
Step(
RunRequest("step1 login")
.post("/api/v1/login/")
.with_headers(
**{
"Content-Type": "application/json",
"User-Agent": "python-requests/2.18.4",
}
)
.with_json({"username": "$user", "password": "$psw"})
.extract()
.with_jmespath("body.token", "token")
.validate()
.assert_equal("status_code", 200)
.assert_equal(‘headers."Content-Type"‘, "application/json")
.assert_equal("body.msg", "login success!")
.assert_equal("body.code", 0)
),
Step(
RunRequest("step2 get user info")
.get("/api/v1/userinfo/")
.with_headers(
**{
"Content-Type": "application/json",
"User-Agent": "python-requests/2.18.4",
"Authorization": "Token $token",
}
)
.validate()
.assert_equal("body.code", 0)
.assert_equal("body.data[0].name", "$user")
),
]
if __name__ == "__main__":
TestCaseUserinfoVar().test_start()
变量优先级
原则上config 变量和 step 变量名称尽量不要重复, 当config和step中都用同一个变量时,step变量优先级大于config变量
config:
name: login case
variables:
user: test
psw: "123456"
base_url: http://127.0.0.1:8000
export:
- token
teststeps:
-
name: step login
variables:
user: test1
psw: "123456"
pytest 对应的脚本
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseLoginVar(HttpRunner):
config = (
Config("login case")
.variables(**{"user": "test", "psw": "123456"})
.base_url("http://127.0.0.1:8000")
.export(*["token"])
)
teststeps = [
Step(
RunRequest("step login")
.with_variables(**{"user": "test1", "psw": "123456"})
config 和 step中都有user变量,运行时,会拿step中的变量值 ‘test1‘去登录。