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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。