创建项目
1.可以先输入hrun --help查看基本的帮助命令
2.创建项目命令
httprunner startporject 项目名称
3.创建完项目文件后可以通过pycharm打开项目并进行编辑
项目解构文件说明
har 存放录制导出的har文件
reports 存放运行报告
testcases 存放测试用例
testsuit 测试集合套件,数据驱动文件夹
.env 全局环境变量管理文件
gitignore git版本管理文件配置
debugtalk.py 调试文件,可编辑运行逻辑代码辅助测试
常用命令
har文件转换为yml测试用例文件操作步骤
1.使用fiddler或者Charles进行接口的抓包
2.然后在fiddler导出接口为har文件
3.把文件复制到har文件夹,然后运行如下命令进行转换
#转为yml文件格式
har2case 文件名.har -2y
#转为json文件格式
har2case 文件名.har -2j
#转换为pytest格式文件
har2case 文件名.har
运行测试用例命令,由于hrun是封装pytest的运行,所有hrun中也可以直接参照pytest的运行格式插入参数;
#运行整个项目的用例,需要在目录的上级路径进行运行
hrun 项目名
#指定运行某个路径下的用例,-s可以查看请求的详细信息
hrun ./testcases/test_har.yml -s
#运行并生成html报告
hrun ./testcases/test_har.yml --html=report.html
#也可以生成pytest的allure报告,需要下载allure-pytest库以及allure插件并配置环境变量,具体可以百度
pip install allure-pytest
#步骤一,运行用例生成allure报告内容
hrun ./testcases/test_har.yml --alluredir=./reports/tmp
#步骤二,根据收集的内容再生成allure报告html文件
allure generate ./reports/tmp -o allure-report --clean # --clean是为了清空已有的测试报告; -o allure-report 是指定清空测试报告的文件allure-report
testcase/demo.py 文件结构说明
# NOTE: Generated By HttpRunner v3.1.4
# FROM: testcases\demo_testcase_request.yml
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseDemoTestcaseRequest(HttpRunner):
config = (
Config("request methods testcase with functions")
.variables(
**{
"foo1": "config_bar1",
"foo2": "config_bar2",
"expect_foo1": "config_bar1",
"expect_foo2": "config_bar2",
}
)
.base_url("https://postman-echo.com")
.verify(False)
.export(*["foo3"])
)
teststeps = [
Step(
RunRequest("get with params")
.with_variables(
**{"foo1": "bar11", "foo2": "bar21", "sum_v": "${sum_two(1, 2)}"}
)
.get("/get")
.with_params(**{"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"})
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.extract()
.with_jmespath("body.args.foo2", "foo3")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.args.foo1", "bar11")
.assert_equal("body.args.sum_v", "3")
.assert_equal("body.args.foo2", "bar21")
),
Step(
RunRequest("post raw text")
.with_variables(**{"foo1": "bar12", "foo3": "bar32"})
.post("/post")
.with_headers(
**{
"User-Agent": "HttpRunner/${get_httprunner_version()}",
"Content-Type": "text/plain",
}
)
.with_data(
"This is expected to be sent back as part of response body: $foo1-$foo2-$foo3."
)
.validate()
.assert_equal("status_code", 200)
.assert_equal(
"body.data",
"This is expected to be sent back as part of response body: bar12-$expect_foo2-bar32.",
)
),
Step(
RunRequest("post form data")
.with_variables(**{"foo2": "bar23"})
.post("/post")
.with_headers(
**{
"User-Agent": "HttpRunner/${get_httprunner_version()}",
"Content-Type": "application/x-www-form-urlencoded",
}
)
.with_data("foo1=$foo1&foo2=$foo2&foo3=$foo3")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.form.foo1", "$expect_foo1")
.assert_equal("body.form.foo2", "bar23")
.assert_equal("body.form.foo3", "bar21")
),
]
if __name__ == "__main__":
TestCaseDemoTestcaseRequest().test_start()
config模块
Config(‘此处输入用例的运行名称’)
.variables 设置环境变量(选填),如果setp中也存在variables ,则以step中的优先
.base_url 测试用例域名(选填),设置了这个的话setp中只能填入相对路径
.verify(选填)
指定是否验证服务器的 TLS 证书。如果我们想记录测试案例执行的 HTTP 请求内容,就需要设置。如果没有设置 verify 属性或者值不为 True,则会发生 SSLError。
通常设置为False,当请求https请求时,就会跳过验证。如果你运行时候发现抛错SSLError,可以检查一下是不是verify没传,或者设置了True。
.export(选填)
这里的导出,主要是为了关联做准备。
比如一个用例的某些响应字段需要在其他的用例中使用时,或者在同一个用例中,某个步骤的结果字段会被另外的结果字段引用,可以将需要提取的字段变量放在 config 的 export 部分。
导出的变量,主要是用于Step之间参数的传递。
Step模块
RunRequest() 请求名称输入
.with_variables(**{key:value}) 定义局部变量,其中里面的 **{}是一个解包操作
.get(/url) 请求的方法以及请求的url,如果定义了base_url,则这里只需要输入相对路径即可,其中request支持的请求方法有如下几种
def get(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.GET, url=url)
return RequestWithOptionalArgs(self.__step_context)
def post(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.POST, url=url)
return RequestWithOptionalArgs(self.__step_context)
def put(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.PUT, url=url)
return RequestWithOptionalArgs(self.__step_context)
def head(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.HEAD, url=url)
return RequestWithOptionalArgs(self.__step_context)
def delete(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.DELETE, url=url)
return RequestWithOptionalArgs(self.__step_context)
def options(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.OPTIONS, url=url)
return RequestWithOptionalArgs(self.__step_context)
def patch(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.PATCH, url=url)
return RequestWithOptionalArgs(self.__step_context)
请求方法下面紧接着的是API的请求参数
#请求参数的输入方法
with_json(**{"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"})
with_params(**{"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"})
with_data("foo1=$foo1&foo2=$foo2&foo3=$foo3")
with_headers(**{key:value}) #请求头
with_cookies(**{key:value})
.extract() 提取响应参数,后面跟着.with_jmespath(参数1,参数2)配合使用
参数1是你目标提取的数据,参数2是把提取的数据赋值给定义的变量值;
.validate() 断言,后面跟着.assert.xx断言操作
特别注意:无论是断言还是提取响应值,提取的第一个值都是body.xxx,因为httprunner默认的返回值是使用body字典进行嵌套的;
变量的调用
1.变量的定义与调用方法
RunTestcase中的call方法
可以在定义步骤时调用RunTestcase方法,然后可以直接调用导入的函数方法,调用时可以自定义变量进行传递,如果原函数中设置了全局变量,则以新传递的变量优先,如果原函数设置了局部变量,则以局部变量优先;