import pytest
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
from lib.common.config_operate import read_ini_config
from testcases.remote_expert.test_001_banner import (
TestCaseTest001Banner as Banner001,
)
from testcases.remote_expert.test_003_banner import (
TestCaseTest003Banner as Banner003,
)
@pytest.mark.skipif(
read_ini_config("Header", "accept-language") == "zh-CN", reason="仅适用于地球外的测试环境"
)
class TestCaseTest002Banner(HttpRunner):
config = (
Config("开启和关闭banner成功")
# 这里可以替换需要配置的参数,当调用用例的时候可以使用 with_variables()重写参数的值
.variables(
**{
"xx": "xx",
"yy": "yy",
}
)
.base_url("${read_ini_config(Host, rem_host_001)}")
.verify(False)
.export("code")
)
teststeps = [
# 测试步骤1
Step(
RunTestCase("前置1:添加一条banner数据")
.setup_hook("${setup_clean_data()}") # 调用用例前执行测试前置
.with_variables( # 更新用例里面的字段值
**{
"xx": "yy",
}
)
.call(Banner001) # 调用用例
.teardown_hook("${teardown_clean_data()}") # 测试后置
.export("xx") # 导出某个值,供下面的步骤使用。这个值来自于本条用例响应内容with_jmespath()
),
Step(RunTestCase("前置2:获取banner页第一行数据ID").call(Banner003).export("id")),
Step(
RunRequest("步骤1:关闭 banner ")
.with_variables(**{"xx": "as"})
.setup_hook("${setup_clean_data()}")
.post(
"/xxxapp/xxxv1/xxxStatus"
)
.with_headers(
**{
"accept-language": "${read_ini_config(Header, accept-language)}",
"autel-token": "${get_login_info(expert_001, token)}",
}
)
.with_json({"id": "$id", "displayStatus": False})
.extract()
.with_jmespath("body.code", "code")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.code", "200")
.assert_equal("body.message", "success")
.assert_equal("body.data", True)
),
]
if __name__ == "__main__":
TestCaseTest002Banner().test_start()
变量优先级:step variables > session variables(runtestcase时带的变量) > parameter variables > config variables
# demo_banner_test.py
import pytest
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
from testcases.pytest测试用例示例.test_001_banner import (
TestCaseTest001Banner as Banner001,
)
from testcases.pytest测试用例示例.test_003_banner import (
TestCaseTest003Banner as Banner003,
)
from httprunner import Parameters
from lib.common.config_operate import read_ini_config
@pytest.mark.skipif(
read_ini_config("Header", "accept-language") == "zh-CN", reason="仅适用于地球外的测试环境"
)
class TestCaseTest002Banner(HttpRunner):
# 变量_全局变量:字段取值参数化
@pytest.mark.parametrize(
"param",
Parameters(
{
"title": "${get_user_id(10)}",
"user": ["user1", "user2"],
"title-user": [("demo4", "4"), ("demo5", "5"), ("dmeo6", "6")],
}
),
)
def test_start(self, param):
super().test_start(param)
config = (
Config("开启和关闭banner成功")
# 变量_全局变量:这里可以替换需要配置的参数,当调用用例的时候可以使用 with_variables()重写参数的值。这里是这条测试用例的全局变量。优先级没有测试步骤里面的高
.variables(
**{
"xx": "xx",
"yy": "yy",
}
)
.base_url("${read_ini_config(Host, rem_host_001)}")
.verify(False)
# 变量_局部变量:该用例被调用时传递出去的变量,可供其他脚本使用
.export("code")
)
teststeps = [
# 测试步骤1
Step(
RunTestCase("前置1:添加一条banner数据")
.setup_hook("${setup_clean_data()}") # 调用用例前执行测试前置
# 变量_局部变量:更新某个 step 里面的字段值
.with_variables(
**{
"xx": "yy",
}
)
.call(Banner001) # 调用用例
.teardown_hook("${teardown_clean_data()}") # 测试后置
# 变量_局部变量:导出某个值,供下面的步骤使用。这个值来自于本条用例响应内容with_jmespath()
.export("xx")
),
Step(RunTestCase("前置2:获取banner页第一行数据ID").call(Banner003).export("id")),
Step(
RunRequest("步骤1:关闭 banner ")
.with_variables(**{"xx": "as"})
# hook_测试前:测试前的清理操作
.setup_hook("${setup_clean_data1()}")
.setup_hook("${setup_clean_data2()}")
.setup_hook("${setup_clean_data3()}")
.post(
"/xxx-app/xxx/operaxxx"
)
.with_headers(
**{
"accept-language": "${read_ini_config(Header, accept-language)}",
"autel-token": "${get_login_info(expert_001, token)}",
}
)
# 变量_引用:使用 ${id} 或者 $id,一般使用 ${id}
.with_json({"id": "$id", "displayStatus": False})
# hook_测试后:测试数据清理
.teardown_hook("${teardown_clean_data4()}")
.teardown_hook("${teardown_clean_data5()}")
# 变量_局部变量:提取响应的参数值
.extract()
.with_jmespath("body.code", "code")
# 校验
.validate()
.assert_equal('headers."Content-Type"', "application/json")
.assert_equal("status_code", 200)
.assert_equal("body.code", "200")
.assert_equal("body.message", "success")
.assert_contains("body.data.records[0].name", "接口自动化")
),
]
if __name__ == "__main__":
TestCaseTest002Banner().test_start()
config:
name: "demo with complex mechanisms"
verify: False
base_url: "https://postman-echo.com"
headers:
X-Request-Timestamp: "165460624942"
parameters:
user_agent: [ "iOS/10.1", "iOS/10.2" ]
username-password: ${parameterize($file)}
parameters_setting:
strategies:
user_agent:
name: "user-identity"
pick_order: "sequential"
username-password:
name: "user-info"
pick_order: "random"
limit: 6
think_time:
strategy: random_percentage
setting:
max_percentage: 1.5
min_percentage: 1
limit: 4
variables:
app_version: v1
user_agent: iOS/10.3
file: examples/hrp/account.csv
websocket:
reconnection_times: 5
reconnection_interval: 2000
export: ["app_version"]
weight: 10
teststeps:
-
name: get with params
variables:
foo1: ${ENV(USERNAME)}
foo2: bar21
sum_v: "${sum_two_int(1, 2)}"
request:
method: GET
url: $base_url/get
params:
foo1: $foo1
foo2: $foo2
sum_v: $sum_v
extract:
foo3: "body.args.foo2"
validate:
- eq: ["status_code", 200]
- eq: ["body.args.foo1", "debugtalk"]
- eq: ["body.args.sum_v", "3"]
- eq: ["body.args.foo2", "bar21"]
-
name: post raw text
variables:
foo1: "bar12"
foo3: "bar32"
request:
method: POST
url: $base_url/post
headers:
Content-Type: "text/plain"
body: "This is expected to be sent back as part of response body: $foo1-$foo2-$foo3."
validate:
- eq: ["status_code", 200]
- eq: ["body.data", "This is expected to be sent back as part of response body: bar12-$expect_foo2-bar32."]
-
name: post form data
variables:
foo2: bar23
request:
method: POST
url: $base_url/post
headers:
Content-Type: "application/x-www-form-urlencoded"
body: "foo1=$foo1&foo2=$foo2&foo3=$foo3"
validate:
- eq: ["status_code", 200]
- eq: ["body.form.foo1", "$expect_foo1"]
- eq: ["body.form.foo2", "bar23"]
- eq: ["body.form.foo3", "bar21"]
暂不投入
暂不投入