目录
1、httprunner概述
1.1、httprunner的优点
2、httprunner的安装
3、基本命令的使用
3.1、生成脚手架
3.2、将har文件转换为测试用例文件
3.3、执行测试用例
3.4、为项目创建虚拟环境,然后安装httprunner库
3.4、执行测试用例生成测试报告
4、httprunner各个模块的使用
4.1、httprunner命名规范
4.2、httprunner的各个模块介绍
4.3、使用RunRequest完成一次接口的请求
4.3.1、测试用例名
4.3.2、请求方式
4.3.3、请求头信息添加
4.3.5、请求参数添加
4.3.6、参数提取
4.3.7、断言
5、全局变量的配置与使用
6、局部变量的配置与使用
7、辅助函数的使用
8、接口参数关联使用
8.1、获取当前用例文件其他已执行Step提取的参数
8.2、获取执行引用测试用例提取出的参数
9、数据驱动
9.1、单组数据驱动
9.2、多组数据驱动
10、文件上传
注:本文使用的httprunner v4.3.0版本与v3.X版本的使用略有不同
pip install httprunner
pip install httprunner==4.3.0
hrp -v
hrp startproject prodject_name
hrp --help
hrp convert --help
# 转换为json格式
hrp convert demo.har --to-json# 转换为pytest格式
hrp convert demo.har --to-pytest# 转换为yaml格式
hrp convert demo.har --to-yaml
hrp run demo_test.json
hrp run demo_test.yaml
hrp run demo_test_test.py
virtualenv env_demo
cd env_demo\Scripts
activate
pip install httprunner==4.3.0
# 使用pytest执行测试用例
pytest demo_test.py
# 使用pytest执行测试用例,并在控制台输出详细日志信息
pytest -s demo_test.py
pip install allure-pytest
pip install "httprunner[allure]"
hrun testcase --alluredir=allure-results --clean-alluredir
参数说明:
allure generate allure-results-path -o allure-report-path -c
参数说明:
-o 指定生成报告的文件夹
-c 在生成报告之前先清理之前的报告目录
allure serve allure-results-path
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
不同模块之间相互关系,以及使用方式:
class TestCaseDemoTest(HttpRunner):
config = Config("testcase description")
teststeps = [
Step(
RunRequest("")
),
Step(
RunTestCase("")
),
]
RunRequest("auth")
示例:
示例:
接口里面参数可以是完整的api URL地址,也可以是只有资源路径的URL地址(这时需要再Config中配置base_url)
如:
或者
.with_headers(
**{
":method": "POST",
":path": "/auth-ws/auth/auth",
":scheme": "https",
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"content-length": "59",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
}
)
with_cookies(
**{
"JSESSIONID": "dgssdggdfhdfghEF6B9487sdgsg4FE",
"lc_cookieid": "a393cbfcfsdfsd94c2537a2",
"lc_sub_client": "h5",
"ngx-auth-ws": "307fdsf192efdsfsdsdgsdsd99bfsd730e",
}
)
1、data类型的参数
.with_data(
{
"password": "admin",
"userName": "test",
"validateCode": "1",
}
)
2、json类型的参数
.with_json(
{
"password": "admin",
"userName": "test",
"validateCode": "1",
}
)
1、响应头参数提取
extract().with_jmespath('headers.Server', 'server')
2、 cookies参数提取
extract().with_jmespath("cookies.token","token")
3、 body参数的提取
.extract().with_jmespath("body.data.sitePortalUrl", "sitePortalUrl")
.extract().with_jmespath("body.data.info_list[0]", "name")
.validate().assert_equal("status_code", 200, "assert response status code")
.validate().assert_greater_than("body.data.count", 100)
config = Config("登录流程").variables(
**{
"userName": "13000000000",
"password": "222",
}
)
.with_data(
{
"password": "$password",
"userName": "$userName",
"validateCode": "1",
}
Step(
RunRequest("用户名密码正确正常登录").with_variables(
**{
"userName": "13000000000",
"password": "222",
}
)
示例:
.with_data(
{
"password": "$password",
"userName": "${get_username($username)}",
"validateCode": "1",
}
)
Step(
RunRequest("auth").with_variables(
**{
"userName": "13000000000",
"password": "222",
}
)
.post("/auth-ws/auth/auth")
.with_headers(
**{
":method": "POST",
":path": "/auth-ws/auth/auth",
":scheme": "https",
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"content-length": "59",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
}
)
.with_cookies(
**{
"JSESSIONID": "dasdsadasBdasds444dsadE",
"lc_cookieid": "asdnksajdkaslsapkfposakf7a2",
"lc_sub_client": "h5",
"ngx-auth-ws": "3dsajdfghiaushassadase",
}
)
.with_data(
{
"password": "$password",
"userName": "${get_username($username)}",
"validateCode": "1",
}
)
.extract()
.with_jmespath("body.data[0].sitePortalUrl", "sitePortalUrl")
.validate()
.assert_equal("status_code", 200, "assert response status code")
Step(
RunRequest("login")
.post("/platform-ms/api/user/login")
.with_headers(
**{
"content-type": "application/json; charset=UTF-8",
}
)
.with_json(
{
"ticket": "${get_ticket($sitePortalUrl)}"
}
)
.extract()
.with_jmespath("headers.token", "token")
.validate()
.assert_equal("status_code", 200, "assert response status code")
)
import pytest
from httprunner import Parameters
from httprunner import HttpRunner, Config, Step, RunRequest, Parameters
import pytest
class TestCaseAuthTest(HttpRunner):
config = Config("登录流程").base_url("http://test.com/")
teststeps = [
Step(
RunRequest("auth")
.post("/auth-ws/auth/auth")
.with_headers(
**{
":method": "POST",
":path": "/auth-ws/auth/auth",
":scheme": "https",
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"content-length": "59",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
}
)
.with_cookies(
**{
"JSESSIONID": "2D4166B552B9487E",
"lc_cookieid": "a393cbfc2",
"lc_sub_client": "h5",
"ngx-auth-ws": "307f4c81190d0fe99b30e",
}
)
.with_data(
{
"password": "$password",
"userName": "$username",
"validateCode": "1",
}
)
.extract()
.with_jmespath("body.data[0].sitePortalUrl", "sitePortalUrl")
.validate()
.assert_equal("status_code", 200, "assert response status code")
)
]
@pytest.mark.parametrize(
"param",
Parameters(
{
"userName": ["test1", "test2", "test3"]
# 也可通过调用debugtalk.py文件中函数获取
# "userName": "${get_username()}"
}
)
)
def test_start(self, param):
super().test_start(param)
from httprunner import HttpRunner, Config, Step, RunRequest, Parameters
import pytest
class TestCaseAuthTest(HttpRunner):
config = Config("登录流程").base_url("http://test.com/")
teststeps = [
Step(
RunRequest("auth")
.post("/auth-ws/auth/auth")
.with_headers(
**{
":method": "POST",
":path": "/auth-ws/auth/auth",
":scheme": "https",
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"content-length": "59",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
}
)
.with_cookies(
**{
"JSESSIONID": "87D154FE",
"lc_cookieid": "a393c2537a2",
"lc_sub_client": "h5",
"ngx-auth-ws": "307f4c8e99b43730e",
}
)
.with_data(
{
"password": "$password",
"userName": "$username",
"validateCode": "1",
}
)
.extract()
.with_jmespath("body.data[0].sitePortalUrl", "sitePortalUrl")
.validate()
.assert_equal("status_code", 200, "assert response status code")
)
]
@pytest.mark.parametrize(
"param",
Parameters(
{
"userName": ["test1", "test2", "test3"]
"passWord": [123, 456, 789]
}
)
)
def test_start(self, param):
super().test_start(param)
pip install "httprunner[upload]"
pip install urllib3==1.25.11
示例如下:
from httprunner import HttpRunner, Config, Step, RunRequest
class TestCaseAddmaterialTest(HttpRunner):
config = Config("testcase description")
teststeps = [
Step(
RunRequest("上传文件")
.post("http://test.com/platform-ms/api/upload/uploadFile")
.with_headers(
**{
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Authorization": "${get_token()}",
"Content-Type": "multipart/form-testdatas; boundary=----WebKitFormBoundaryi26ZrOKdu2tMFYa7",
}
)
.with_params(
**{
"businessKey": "material",
"picUrl": "(binary)"
}
)
.upload(**{"file": r"E:\WorkPlace\test\demo\CS.png", "title": "测试图片上传"})
.validate()
.assert_equal("status_code", 200, "assert response status code")
)