pytest中setup()函数异常行为原因及冲突函数名咨询
setup() cause a pytest error? Let's break down what's happening here and how to avoid similar issues.
The Root Cause
Pytest maintains compatibility with x-unit style test fixtures, which includes automatically recognizing certain function names as setup/teardown hooks at different scopes.
In your case, you named your function setup() at the module level. Pytest interprets this as the legacy module-level x-unit setup hook, which expects no arguments. But your setup() function requires a conf_func parameter. When pytest tries to run this hook automatically (without passing any arguments) during test setup, it hits a parameter mismatch error—this is exactly the exception you're seeing.
When you rename the function to setup_func() or something else, pytest no longer treats it as a built-in hook, so your @pytest.mark.parametrize call can use it normally to generate test parameters.
Your Code for Reference
Problematic Code
import pytest def config(): login = 'John' password = '123' env = 'staging' return login, password, env def setup(conf_func): return [conf_func()] @pytest.mark.parametrize('login, password, env', setup(config)) def test_func(login, password, env): print(login, password, env) assert False
Error Snippet
============================= test session starts ============================= platform win32 -- Python 3.6.8, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 rootdir: C:\python\experiments\fixtures collected 1 item test_fix6.py E test setup failed cls = <class '_pytest.runner.CallInfo'> func = <function call_runtest_hook.<locals>.<lambda> at 0x0000000003AA6B70> when = 'setup' reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() venv\lib\site-packages\_pytest\runner.py:220: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ venv\lib\site-packages\_pytest\runner.py:192: in <lambda> lambda: ihook(item=item, **kwds), when=when, reraise=reraise venv\lib\site-packages\pluggy\hooks.py:289: in __call__ return self._hookexec(self, self.get_hookimpls(), kwargs) venv\lib\site-packages\pluggy\manager.py:87: in _hookexec return self._inner_hookexec(hook, methods, kwargs) venv\lib\site-packages\pluggy\manager.py:81: in <lambda> firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, venv\lib\site-packages\_pytest\nose.py:34: in pytest_runtest_setup call_optional(item.parent.obj, "setup")
Other Function Names to Avoid
To prevent similar conflicts, avoid using these x-unit style hook names in your test modules (unless you intend to use them as setup/teardown hooks):
Module Scope
setup()(legacy module setup, no arguments)teardown()(legacy module teardown, no arguments)setup_module()(modern module setup, accepts a module parameter)teardown_module()(modern module teardown, accepts a module parameter)
Class Scope (inside test classes)
setup_class()(runs once before all methods in the class, accepts cls parameter)teardown_class()(runs once after all methods in the class, accepts cls parameter)setup_method()(runs before each test method, accepts self parameter)teardown_method()(runs after each test method, accepts self parameter)
Function Scope (for standalone test functions)
setup_function()(runs before each test function, accepts a function parameter)teardown_function()(runs after each test function, accepts a function parameter)
Sticking to non-reserved names for your helper functions will keep pytest from misinterpreting them as built-in hooks.
内容的提问来源于stack exchange,提问作者Andrey Glazkov

