如何在scikit-learn的parametrize_with_checks中使用pytest fixture?
解决方法
方法1:使用pytest-lazy-fixture插件(简单快捷)
这个插件支持在参数化装饰器中直接引用pytest fixture,完美适配你的场景:
- 先安装插件:
pip install pytest-lazy-fixture
- 修改测试代码:
import pytest from sklearn.linear_model import LinearRegression from sklearn.utils.estimator_checks import parametrize_with_checks from pytest_lazyfixture import lazy_fixture @pytest.fixture def models(): return (LinearRegression(fit_intercept=flag) for flag in (False, True)) class TestModels: # 用lazy_fixture包装fixture名称,传递给parametrize_with_checks @parametrize_with_checks(lazy_fixture("models")) def test_1(self, estimator, check): check(estimator) print("Do other stuff...") def test_2(self, models): print("Do even more stuff...")
方法2:原生pytest钩子实现(无需额外插件)
如果不想引入第三方插件,可以借助pytest_generate_tests钩子函数,在测试收集阶段动态获取fixture实例化后的估算器列表,再生成检查用例:
import pytest from sklearn.linear_model import LinearRegression from sklearn.utils.estimator_checks import _generate_checks @pytest.fixture def models(): return [LinearRegression(fit_intercept=flag) for flag in (False, True)] def pytest_generate_tests(metafunc): # 检查当前测试函数是否需要处理估算器检查 if "estimator" in metafunc.fixturenames and "check" in metafunc.fixturenames: # 获取自定义标记中指定的fixture名称 fixture_marker = metafunc.definition.get_closest_marker("use_estimator_fixture") if fixture_marker: fixture_name = fixture_marker.args[0] # 获取fixture对应的估算器列表 estimators = metafunc.getfixturevalue(fixture_name) # 生成和parametrize_with_checks一致的检查用例 test_cases = _generate_checks(estimators) # 为测试函数参数化 metafunc.parametrize("estimator, check", test_cases) class TestModels: # 添加自定义标记,指定要使用的fixture名称 @pytest.mark.use_estimator_fixture("models") def test_1(self, estimator, check): check(estimator) print("Do other stuff...") def test_2(self, models): print("Do even more stuff...")
原理说明
parametrize_with_checks在测试收集阶段就会执行,此时直接传入fixture函数对象(而非实例化后的值)必然报错。两种方法都是在合适的时机获取到fixture实例化后的估算器列表,再对接scikit-learn的检查逻辑。
内容的提问来源于stack exchange,提问作者Ross B.
相关产品推荐
相关产品推荐

