HttpRunner3和2的区别挺大,3的底层使用pytest
,2的底层是unittest
.
在兼容json和yaml格式测试用例的前提下,作者更鼓励使用写代码来接入.
具体可以看这篇文章分析对比
cli.py
命令行驱动的库很容易找到入口地址. 在这个文件内,主要有以下方法:
main()
, 使用argparse
接收用户输入的命令,决定走哪个方法,关键代码 if sys.argv[1] == "run":
sys.exit(main_run(extra_args))
elif sys.argv[1] == "startproject":
main_scaffold(args)
elif sys.argv[1] == "har2case":
main_har2case(args)
elif sys.argv[1] == "make":
main_make(args.testcase_path)
main_run()
方法
首先判断httprunner run xxx
的路径xxx
在系统里是否存在.
然后47行,testcase_path_list = main_make(tests_path_list)
会调用make.py
里的main_make()
方法,把json
,yml
等格式的文件,转化为pytest
能执行的.py
文件. (make.py
文件有600多行,主要就是将json,yml
文件转为pytest格式.)
在make.py
的528行,test_content = load_test_file(test_file)
,导出的文件test_content
是Dict
格式.
最后会是合法的testcase
目录或者文件,调用pytest.main('用例列表')
main_har2case()
将har
文件转为测试文件,默认转为pytest使用的Text_xxx.py
main_scaffold()
创建一个httprunner标准工程文件夹
cli.py
里的其他内容,就是定义har2case
,hrun
等缩写命令
代码里分别用yaml.load()
和json.load()
将yml和json文件转为字典Dict格式
读取yml文件原始内容是:
config:
name: "request methods testcase: reference testcase"
variables:
foo1: testsuite_config_bar1
expect_foo1: testsuite_config_bar1
expect_foo2: config_bar2
base_url: "https://postman-echo.com"
verify: False
teststeps:
-
name: request with functions
variables:
foo1: testcase_ref_bar1
expect_foo1: testcase_ref_bar1
testcase: testcases/demo_testcase_request.yml
export:
- foo3
-
name: post form data
variables:
foo1: bar1
request:
method: POST
url: /post
headers:
User-Agent: HttpRunner/${get_httprunner_version()}
Content-Type: "application/x-www-form-urlencoded"
data: "foo1=$foo1&foo2=$foo3"
validate:
- eq: ["status_code", 200]
- eq: ["body.form.foo1", "bar1"]
- eq: ["body.form.foo2", "bar21"]
框架转换后的格式为:
{
'config': {
'name': 'request methods testcase: reference testcase',
'variables': {
'foo1': 'testsuite_config_bar1',
'expect_foo1': 'testsuite_config_bar1',
'expect_foo2': 'config_bar2'
},
'base_url': 'https://postman-echo.com',
'verify': False
},
'teststeps': [{
'name': 'request with functions',
'variables': {
'foo1': 'testcase_ref_bar1',
'expect_foo1': 'testcase_ref_bar1'
},
'testcase': 'testcases/demo_testcase_request.yml',
'export': ['foo3']
}, {
'name': 'post form data',
'variables': {
'foo1': 'bar1'
},
'request': {
'method': 'POST',
'url': '/post',
'headers': {
'User-Agent': 'HttpRunner/${get_httprunner_version()}',
'Content-Type': 'application/x-www-form-urlencoded'
},
'data': 'foo1=$foo1&foo2=$foo3'
},
'validate': [{
'eq': ['status_code', 200]
}, {
'eq': ['body.form.foo1', 'bar1']
}, {
'eq': ['body.form.foo2', 'bar21']
}]
}]
}
||
小技巧from httprunner.ext.har2case import init_har2case_parser, main_har2case
from httprunner.make import init_make_parser, main_make
from httprunner.scaffold import init_parser_scaffold, main_scaffold
from httprunner.utils import init_sentry_sdk
if test_file.lower().endswith("_test.py"):
loader.py
文件里.loader.py
里导入测试用例时,用Pydantic
库来验证数据类型, testcase_obj = TestCase.parse_obj(testcase)
将对象加载到模型中,如果对象不是字典则报错.os.sep.join()
消除linux和windows平台的文件路径差异pydantic
定义类的数据类型 if len(sys.argv) >= 2 and sys.argv[1] in ["run", "locusts","define"]:
args, extra_args = parser.parse_known_args() # 接收额外参数
# 执行 python3 test.py run tt01/testcases/login_battle_test.py
# args is : Namespace(version=False)
# extra_args is : ['tt01/testcases/login_battle_test.py']
else:
args = parser.parse_args()
# 执行 python3 test.py har2case tt01/testcases/login_battle_test.py
# args is Namespace(exclude=None, filter=None, har_source_file='tt01/testcases/login_battle_test.py', to_json=False, to_yaml=False, version=False)
for item in extra_args:
if not os.path.exists(item):
# item is not file/folder path
extra_args_new.append(item)
else:
# item is file/folder path
tests_path_list.append(item)
httprunner框架在单纯处理最后发起自动化交易请求之外,有较大的精力需要去处理测试用例文件的问题,例如判断当前文件路径,文件格式转换,
pytest: error: unrecognized arguments: --html=report.html
报错是因为需要额外安装 pip install pytest-html
。
pytest-html 是pytest的插件,不属于pytest库。
Python中最好用的命令行解析工具:argparse