httprunner是什么
运行CLI后有这么一段,我就直接拿过来用了
██╗ ██╗████████╗████████╗██████╗ ██████╗ ██╗ ██╗███╗ ██╗███╗ ██╗███████╗██████╗
██║ ██║╚══██╔══╝╚══██╔══╝██╔══██╗██╔══██╗██║ ██║████╗ ██║████╗ ██║██╔════╝██╔══██╗
███████║ ██║ ██║ ██████╔╝██████╔╝██║ ██║██╔██╗ ██║██╔██╗ ██║█████╗ ██████╔╝
██╔══██║ ██║ ██║ ██╔═══╝ ██╔══██╗██║ ██║██║╚██╗██║██║╚██╗██║██╔══╝ ██╔══██╗
██║ ██║ ██║ ██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║██║ ╚████║███████╗██║ ██║
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝
HttpRunner is an open source API testing tool that supports HTTP(S)/HTTP2/WebSocket/RPC
network protocols, covering API testing, performance testing and digital experience
monitoring (DEM) test types. Enjoy! ✨ 🚀 ✨
License: Apache-2.0
Website: https://httprunner.com
Github: https://github.com/httprunner/httprunner
Copyright 2017 debugtalk
HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型。简单易用,功能强大,具有丰富的插件化机制和高度的可扩展能力。
一、设计理念
相比于其它 API 测试工具,HttpRunner 最大的不同在于设计理念。
- 约定大于配置:测试用例是标准结构化的,格式统一,方便协作和维护
- 标准开放:基于开放的标准,支持与 HAR/Postman/Swagger/Curl/JMeter 等工具对接,轻松实现用例生成和转换
- 一次投入多维复用:一套脚本可同时支持接口自动化测试、性能测试、数字体验监测等多种 API 测试需求
- 融入最佳工程实践:不仅仅是一款测试工具,在功能中融入最佳工程实践,实现面向网络协议的一站式测试解决方案
二、核心特性
- 网络协议:完整支持 HTTP(S)/1.1 和 HTTP/2,可扩展支持 WebSocket/TCP/RPC 等更多协议
- 多格式可选:测试用例支持 YAML/JSON/go test/pytest 格式,并且支持格式互相转换
- 双执行引擎:同时支持 golang/python 两个执行引擎,兼具 go 的高性能和 pytest 的丰富生态
- 录制 & 生成:可使用 HAR/Postman/Swagger/curl 等生成测试用例;基于链式调用的方法提示也可快速编写测试用例
- 复杂场景:基于 variables/extract/validate/hooks 机制可以方便地创建任意复杂的测试场景
- 插件化机制:内置丰富的函数库,同时可以基于主流编程语言(go/python/java)编写自定义函数轻松实现更多能力
- 性能测试:无需额外工作即可实现压力测试;单机可轻松支撑 1w+ VUM,结合分布式负载能力可实现海量发压
- 网络性能采集:在场景化接口测试的基础上,可额外采集网络链路性能指标(DNS 解析、TCP 连接、SSL 握手、网络传输等)
- 一键部署:采用二进制命令行工具分发,无需环境依赖,一条命令即可在 macOS/Linux/Windows 快速完成安装部署 用户声音
有兴趣的同学可以直接访问官网 httprunner官网链接
三、优化建议及临时修改方案
我大概花了一个星期来熟悉整个框架并通过框架的能力实现了一套完整的接口自动化测试框架,但是其中也有不少问题出现:
1.CLI参数不够强大,没有完全兼容自动化测试常用的参数
hrp pytest CLI参数没有兼容pytest中的一些参数,所以我建议如果是使用python去做自动化的话直接使用hrun命令
[pytest]
addopts = -vs --alluredir=reports/temp --clean-alluredir
按照提示在环境变量中设置也是一样的效果,识别不了参数–alluredir和–clean-alluredir
PYTEST_ADDOPTS=-vs --alluredir=reports/temp --clean-alluredir
Environment variables:
PYTEST_ADDOPTS Extra command line options
2.日志文件不易查阅
a)中文存在乱码,可以修改runner.py文件修复此问题
##### runner.py文件中大概227行
logger.add(self.__log_path, format=LOGGER_FORMAT, level="DEBUG", encoding='utf-8')
b)日志名字是使用的uuid来命名的,当日志比较的时候不太好查看本次运行日志,我自己使用时修改日志名称,用时间戳来命名日志名称的
### 定义了一个变量log_id,取时间戳拼接日志名称,也是runner.py文件中,大概67行
self.log_id = datetime.now().strftime('%Y-%m-%d_%H-%M')
self.__log_path = os.path.join(self.root_dir, "logs", f"{self.log_id}.run.log")
c)使用hrp pytest运行用例时,上述修改的日志文件没有效果,由于本人代码能力较差,希望大佬能帮忙指出如何修改
3.断言失败没有抛出异常
断言失败不抛出异常会导致allure报告中显示的用例测试结果为broken,这样不方便查阅报告,所以我对框架中的respone.py文件添加抛出异常的操作
####respone.py文件大概248行
logger.error(validate_msg)
failures.append(validate_msg)
raise ex
4.hrp pytest命令上传文件接口报错
hrp pytest -vs xxx.yaml
报错信息如下(依赖的这些扩展库都已经安装过了):
2023-05-25 11:32:06.512 | ERROR |
uploader extension dependencies uninstalled, install first and try again.
install with pip:
$ pip install requests_toolbelt filetype
or you can install httprunner with optional upload dependencies:
$ pip install "httprunner[upload]"
2023-05-25 11:32:06.513 | INFO | generate testcase log: D:\autotest\PycharmProjects\locust\demo\logs\75388a8d-29d0-46c7-9fa8-cbea4ce28bb8.run.log
2023-05-25 11:32:06.514 | INFO | generate testcase log: D:\autotest\PycharmProjects\locust\demo\logs\75388a8d-29d0-46c7-9fa8-cbea4ce28bb8.run.log
FAILED
实际使用过程还发现,如果不带参数vs还会出现这样的报错:
Record was: {'elapsed': datetime.timedelta(seconds=1, microseconds=735665), 'exception': None, 'extra': {}, 'file': (name='runner.py', path='C:\\Users\\Lee\\.hrp\\venv\\lib\\site-packages\\httprunner\\runner.py'),
'function': 'test_start', 'level': (name='INFO', no=20, icon='ℹ️'), 'line': 233, 'message': 'generate testcase log: D:\\autotest\\PycharmProjects\\locust\\demo\\logs\\fc98e2cd-09d7-495f-bf89-b5715f978a62.run.log'
, 'module': 'runner', 'name': 'httprunner.runner', 'process': (id=3724, name='MainProcess'), 'thread': (id=16276, name='MainThread'), 'time': datetime(2023, 5, 25, 11, 33, 54, 495161, tzinfo=datetime.timezone(date
time.timedelta(seconds=28800), '中国标准时间'))}
Traceback (most recent call last):
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\runner.py", line 231, in test_start
self.__run_step(step)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\runner.py", line 190, in __run_step
step_result: StepResult = step.run(self)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step.py", line 67, in run
return self.__step.run(runner)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step_testcase.py", line 70, in run
return run_step_testcase(runner, self.__step)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step_testcase.py", line 25, in run_step_testcase
ref_case_runner.set_referenced().with_session(runner.session).with_case_id(
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\runner.py", line 231, in test_start
self.__run_step(step)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\runner.py", line 190, in __run_step
step_result: StepResult = step.run(self)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step.py", line 67, in run
return self.__step.run(runner)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step_request.py", line 348, in run
return run_step_request(runner, self.__step)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\step_request.py", line 92, in run_step_request
prepare_upload_step(step, step_variables, functions)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\ext\uploader\__init__.py", line 107, in prepare_upload_step
ensure_upload_ready()
File "C:\Users\Lee\.hrp\venv\lib\site-packages\httprunner\ext\uploader\__init__.py", line 75, in ensure_upload_ready
sys.exit(1)
SystemExit: 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Lee\.hrp\venv\lib\site-packages\loguru\_handler.py", line 177, in emit
self._sink.write(str_record)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\loguru\_simple_sinks.py", line 26, in write
self._stream.write(message)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\colorama\ansitowin32.py", line 47, in write
self.__convertor.write(text)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\colorama\ansitowin32.py", line 177, in write
self.write_and_convert(text)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\colorama\ansitowin32.py", line 202, in write_and_convert
self.write_plain_text(text, cursor, start)
File "C:\Users\Lee\.hrp\venv\lib\site-packages\colorama\ansitowin32.py", line 211, in write_plain_text
self.wrapped.flush()
OSError: [WinError 6] 句柄无效。
--- End of logging error ---
参考了github上面大佬的各种方案,目前还没有解决,如有解决的同学麻烦留言告诉我一下,ღ( ´・ᴗ・` )比心
5.后置处理顺序优化
当前测试用例执行步骤为先执行teardown hooks然后再执行extract,实际测试中这样的顺序是不合理的,因为我们在后置处理中可能会使用到extract中的数据,所以需要调整两者的顺序,先执行extract再执行teardown hooks,修改step_request.py文件中161行位置,把源码中teardown hooks下面两行代码到移到variables_mapping这行后面