diff --git a/CHANGELOG b/CHANGELOG index 4d3d99b9f..08ebea21e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,10 @@ Changes between 2.3.4 and 2.3.5dev ----------------------------------- +- never consider a fixture function for test function collection + - allow re-running of test items / helps to fix pytest-reruntests plugin - and also should help to keep less fixture/resource references alive + and also help to keep less fixture/resource references alive - put captured stdout/stderr into junitxml output even for passing tests (thanks Adam Goucher) diff --git a/_pytest/python.py b/_pytest/python.py index 34e7fffbd..b78e33513 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -177,7 +177,8 @@ def pytest_pycollect_makeitem(__multicall__, collector, name, obj): if collector.classnamefilter(name): Class = collector._getcustomclass("Class") return Class(name, parent=collector) - elif collector.funcnamefilter(name) and hasattr(obj, '__call__'): + elif collector.funcnamefilter(name) and hasattr(obj, '__call__') and \ + getfixturemarker(obj) is None: if is_generator(obj): return Generator(name, parent=collector) else: @@ -1566,15 +1567,7 @@ class FixtureManager: continue # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style) # or are "@pytest.fixture" marked - try: - marker = obj._pytestfixturefunction - except KeyboardInterrupt: - raise - except Exception: - # some objects raise errors like request (from flask import request) - # we don't expect them to be fixture functions - marker = None - + marker = getfixturemarker(obj) if marker is None: if not name.startswith(self._argprefix): continue @@ -1771,6 +1764,18 @@ def getfuncargparams(item, ignore, scopenum, cache): def xunitsetup(obj, name): meth = getattr(obj, name, None) - if meth is not None: - if not hasattr(meth, "_pytestfixturefunction"): - return meth + if getfixturemarker(meth) is None: + return meth + +def getfixturemarker(obj): + """ return fixturemarker or None if it doesn't exist or raised + exceptions.""" + try: + return getattr(obj, "_pytestfixturefunction", None) + except KeyboardInterrupt: + raise + except Exception: + # some objects raise errors like request (from flask import request) + # we don't expect them to be fixture functions + return None + diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 02cd55c21..938555002 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1641,6 +1641,20 @@ class TestFixtureMarker: reprec = testdir.inline_run("-v") reprec.assertoutcome(passed=6) + def test_fixture_marked_function_not_collected_as_test(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture + def test_app(): + return 1 + + def test_something(test_app): + assert test_app == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + class TestRequestScopeAccess: pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[ ["session", "", "fspath class function module"], diff --git a/testing/test_assertion.py b/testing/test_assertion.py index c85bec336..02199ef43 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -101,7 +101,7 @@ class TestAssert_reprcompare: def test_frozenzet(self): expl = callequal(frozenset([0, 1]), set([0, 2])) - print expl + print (expl) assert len(expl) > 1 def test_list_tuples(self):