nosetests迁移至pytest后测试套件耗时激增的技术咨询
解决pytest替代nosetests后测试速度暴慢的问题
你遇到的核心问题其实是pytest对nosetests风格的模块级setup/teardown默认处理逻辑和nosetests不一致,直接导致每个测试函数都重复执行数据库创建操作,总耗时被拉爆了。
先拆解下根因:
- 在nosetests中,测试文件里的
setup()默认是模块级的——每个.py测试文件只执行一次数据库创建,整个文件里的测试用例共用这个数据库实例。 - 但pytest默认会把这种nosetests风格的
setup()识别为函数级的——每个测试函数跑之前都会执行一次setup(),等于585个测试要创建585次数据库,时间自然翻了几十倍。
下面给你两个不用逐个修改测试用例的解决方案:
方案1:用pytest-nose插件完全兼容nosetests行为
这个方案不需要改任何测试代码,直接让pytest按照nosetests的规则处理setup/teardown:
- 安装插件:
pip install pytest-nose - 修改你的
pytest.ini,添加兼容参数:[pytest] python_files = tests_*.py *_tests.py norecursedirs = .idea (pycharm env) testpaths = tests addopts = --nosetests - 重新运行pytest,现在它会把测试文件里的
setup()当作模块级方法执行,每个测试文件只创建一次数据库,速度应该会和nosetests接近。
方案2:用conftest.py全局注入模块级fixture(无需逐个加装饰器)
如果不想依赖第三方插件,可以用pytest的autouse fixture全局统一处理数据库创建,只需在tests目录下新建conftest.py文件:
import pytest # 导入你的数据库创建函数 from mod1.core import get_new_db # 定义模块级fixture,autouse=True会自动应用到所有测试模块 @pytest.fixture(scope='module', autouse=True) def global_db(): # 替代原来的setup()逻辑 db = get_new_db() yield db # 所有测试函数执行期间都用这个db实例 # 这里可以加原来teardown需要的逻辑(比如关闭连接、清理文件)
之后你可以把测试文件里的setup()函数删掉,测试函数里的db会自动被这个fixture注入(如果原来的测试用了global db,只需要统一去掉全局声明,直接用fixture的db参数即可,不需要逐个测试用例修改)。
快速验证方法
你可以先跑单个测试文件验证效果:比如执行pytest tests/test_mod1/xxx_test.py -v,看看数据库是不是只创建一次,耗时是不是和nosetests跑这个文件的时间接近。
内容的提问来源于stack exchange,提问作者root-11
相关产品推荐
相关产品推荐

