pytest使用总结及采坑指南
pytest总结
- pytest一个非常优秀的点就是可以支持扩展很多插件。
- 安装python工具包时,时长遇到访问连接不到仓库的情况,使用-i命令指定仓库地址,通常我都是选择这个地址:
https://mirrors.ustc.edu.cn/p... - pytest插件如下及功能介绍:
- 安装pytest:pip3 install pytest -i https://mirrors.ustc.edu.cn/p...
-
由于项目测试中希望重复执行,所以使用pytest-repeat插件
--count=2, 指定测试的次数,默认是函数级别的测试
--repeat-scope, 指定重复执行的域.
- 补充说明:pytest有一个域的概念即scope,分为function、class、module、session
- 其中function指一个test开头的函数,class指一个Test开头的类,而module指一个test开头的文件,session指这次执行的所有用例。
- 所以说如果--repeat-scope指定了session则表明是按照session进行重复。
- 注意:经过测试--xdist命令下不能按照预期的repeat-scope进行执行。
- 例子:
pytest test1.py -s --count=5 --repeat-scope=session
- 通过在函数上添加@pytest.mark.repeat(count)装饰,指定函数执行次数。
@pytest.mark.repeat(5) def test_02(start, open_baidu): print("测试用例test_02")
- pytest-xdist, 并发执行多个非依赖用例
- 解释一下,--xdist选项目的是为了节省测试用例的执行时间,使用多核执行测试用例,但是有个前提条件就是这些用例不存在依赖关系,因为依赖关系是不能被保证的,及时有后边提到的ordering、dependancy插件
- 安装pip3 install pytest-xdist -i https://mirrors.ustc.edu.cn/p...
- 用法:
pytest test.py -n auto
指示根据当前cpu信息自动分配合理的核数运行用例,同样可以使用pytest test.py -n 3
指定具体的运行核数,并发进程数
- pytest相对简单的保证项目用例前后顺序的插件
pytest-ordering
- 安装:pip3 install pytest-ordering -i
https://mirrors.ustc.edu.cn/p... - 使用方法:
@pytest.mark.run(order=7)
def test_delete_port(self, host_ip, module_dict, cfg):
if "test_create_port" not in module_dict:
# skip
pytest.skip("do not have test_create_port result")
self.delete_port(host_ip, module_dict)
@pytest.mark.run(order=8)
def test_delete_subnet(self, host_ip, module_dict, cfg, db_session):
if "test_create_vpc_subnet" not in module_dict:
# skip
pytest.skip("do not have test_create_port result")
self.delete_subnet(host_ip, module_dict, db_session)
两段代码会先执行7在执行8,如果不指定,则按照名字排序执行。
- 自定义参数
- 有时我们需要根据不同的场景传入一下参数,参考如下代码即可:
# pytest_addoption是pytest已经定义好的fixture(固件)可以直接使用,指定要解析的字段,action表示存储格式
def pytest_addoption(parser):
parser.addoption("--cmdopt", action="store", default="dev.ini", help="my option: type1 or type2")
parser.addoption("--concurrency", action="store", default='False', help="my option: concurrency")
# 定义自己的固件,即其他测试用例通过哪个名字获取这个定义的--cmdopt参数
@pytest.fixture(scope="module")
def cmdopt(request):
return request.config.getoption("--cmdopt")
- 生成报告:
- 使用简单的pytest-html插件
只需要安装pip3 install pytest-html
运行命令pytest test.py --html=./report.html,指定输出的文件为report.html报告 -
使用allure工具,界面好看,功能全,安装复杂
- 需要安装allure插件及工具
- 安装allure brew install allure
- 安装插件pip3 install allure-pytest -i https://mirrors.ustc.edu.cn/p...
- 执行命令:pytest -v test_vpc_floatingip.py -n auto --count=5 -q --alluredir ./report
- allure generate --clean report/ -o allure-results/ #生成html格式文件
- allure open ./allure-results/ 打开文件
- 备注:allure使用了两种方式来渲染页面,分别是allure open 和 allure serve。前者用于在本地渲染和查看结果,后者用于在本地渲染后对外展示结果,所以要想查看有数据的html内容,需要使用allure open。运行命令 allure open allure-report即可自动打开浏览器(耐心等待一下)展示渲染好的结果,其中allure-report为allure generate生成的结果所在目录。
- 有些人会使用pip3 install pytest-allure-adaptor -i https://mirrors.ustc.edu.cn/p... 会报错:
INTERNALERROR> AttributeError: module 'pytest' has no attribute ‘allure’,卸载安装l allure-pytest,但我这里会报错,所以未使用 - 重复执行多次,allure会记录多次的结果,但是总的用例数是不变的,但是某一个用例的重复次数会增加
- 重点:我的项目测试用例之间有依赖关系,又不想整合到一起会丢失很多test_case细节,又想要并发将此流程执行多遍,此时简单的使用repeate ordering xdist插件终究不能满足自己的需求,最后只能利用如下方式:
main函数:
def run(i):
file_name = '--html=./report/report_{}.html'.format(i[0])
pytest.main(["-v", "-s", '--log-format="%(asctime)s %(levelname)s %(message)s"',
'--log-date-format="%Y-%m-%d %H:%M:%S"', file_name, '', '--alluredir', './report/result', i[1]])
# pytest.main(['-v', '--alluredir', 'report/result'])
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
p1 = '--cmdopt={}'.format(sys.argv[1])
num = int(sys.argv[2])
else:
p1 = '--cmdopt=dev.ini'
num = 1
import multiprocessing
pool = multiprocessing.Pool(4)
_list = [(x, p1) for x in range(num)]
pool.map(run, _list)
pool.close()
pool.join()
- 关于日志输出:
可以通过指定 --log-format="%(asctime)s %(levelname)s %(message)s" 和 --log-date-format="%Y-%m-%d %H:%M:%S"分别指定日志的格式和日志的日期格式 - 通过pytest.ini指定pytest运行时参数
pytest的执行可以分为几种,一种是最常见的pytest test.py形式
第二种是直接执行pytest,第三种是执行python test.py但此时的test.py内容应该是第7节中的run中的pytest.main的运行形式
值得注意的是,不管哪种形式pytest都会先找pytest.ini进行加载,如果有覆盖的信息会被覆盖,否则就使用pytest.ini内容
开启日志功能使用log_cli=true
[pytest]
; addopts = -s -v --html=report/report.html --alluredir ./report/result --count=1 -n auto
testpaths = ./
#python_files = test_*.py
#python_classes = Test*
log_cli=true
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_level = INFO
#log_level=NOTSET
log_file = ./logs/pytest-logs.txt
python_functions = test*
参考:
https://www.jianshu.com/p/ddb...
https://www.cnblogs.com/yoyok... 使用skip跳过用例
https://blog.csdn.net/qq_42610167/article/details/101204066?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
推荐阅读
go-ovn源码阅读思考
最近在学习ovn相关的内容,需要通过go-ovn库实现向ovn写入信息。go-ovn的源码实现大致实现功能简单梳理一下:go-ovn 代码的核心思想就是封装了libovsdb库,将rpc接口修改为了api接口,定义了marshal unmarshal的...
neilliu阅读 1.7k
又一款眼前一亮的Linux终端工具!
今天给大家介绍一款最近发现的功能十分强大,颜值非常高的一款终端工具。这个神器我是在其他公众号文章上看到的,但他们都没把它的强大之处介绍明白,所以我自己体验一波后,再向大家分享自己的体验。
良许赞 6阅读 1.9k
FastAPI性能碾压Flask?
不止一次的听过,FastAPI性能碾压Flask,直追Golang,不过一直没有测试过,今天闲着没事测试一下看看结果。不知道是哪里出了问题,结果大跌眼镜。
二毛erma0赞 2阅读 10.3k评论 3
Linux终端居然也可以做文件浏览器?
大家好,我是良许。在抖音上做直播已经整整 5 个月了,我很自豪我一路坚持到了现在【笑脸】最近我在做直播的时候,也开始学习鱼皮大佬,直播写代码。当然我不懂 Java 后端,因此就写写自己擅长的 Shell 脚本。但...
良许赞 1阅读 2.1k
Python之如何优雅的重试
为了避免偶尔的网络连接失败,需要加上重试机制,那么最简单的形式就是在对应的代码片段加一个循环,循环体里使用异常捕获,连接成功时退出循环,否则就重复执行相关逻辑,此时修改之后的函数f如下
Harpsichord1207赞 3阅读 7.4k
基于 EKS Fargate 搭建微服务性能分析系统
近期 Amazon Fargate 在中国区正式落地,因 Fargate 使用 Serverless 架构,更加适合对性能要求不敏感的服务使用,Pyroscope 是一款基于 Golang 开发的应用程序性能分析工具,Pyroscope 的服务端为无状态服务且性...
亚马逊云开发者阅读 7.8k
ChatGPT的开源平替,终于来了!
最近这段时间,一个号称全球最大ChatGPT开源平替项目Open Assistant引起了大家的注意。这不最近还登上了GitHub的Trending热榜。[链接]根据官方的介绍,Open Assistant也是一个对话式的大型语言模型项目,可以理解...
CodeSheep赞 2阅读 1.1k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。