Skip to content

Commit 3ba2a75

Browse files
committed
Skip pytest fixture functions when collecting.
Fixes #9.
1 parent 20d89c5 commit 3ba2a75

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

docs/changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
Changelog
33
=========
44

5+
- :bug:`9` Don't try loading Pytest fixture functions as if they were test
6+
functions. Classifying this as a bug even though it's a moderately sized
7+
change in behavior; it's vanishingly unlikely anybody was relying on this
8+
somehow! Thanks to ``@cajopa`` for the report.
59
- :release:`2.0.0 <2022-12-31>`
610
- :bug:`- major` Prior to version 2, we failed to correctly support true Pytest
711
setup/teardown methods (i.e. ``setup_method`` and ``teardown_method``) and

pytest_relaxed/classes.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,18 @@ def istestclass(name):
1818
return not name.startswith("_")
1919

2020

21-
def istestfunction(name):
22-
return not (
23-
name.startswith("_")
24-
or name in ("setup", "setup_method", "teardown", "teardown_method")
21+
# NOTE: this is defined at top level due to a couple spots of reuse outside of
22+
# the mixin class itself.
23+
def istestfunction(obj, name):
24+
is_hidden_name = name.startswith("_") or name in (
25+
"setup",
26+
"setup_method",
27+
"teardown",
28+
"teardown_method",
2529
)
30+
# TODO: is this reliable? how about __pytest_wrapped__?
31+
is_fixture = hasattr(obj, "_pytestfixturefunction")
32+
return not (is_hidden_name or is_fixture)
2633

2734

2835
# All other classes in here currently inherit from PyCollector, and it is what
@@ -45,7 +52,7 @@ def istestclass(self, obj, name):
4552
return istestclass(name)
4653

4754
def istestfunction(self, obj, name):
48-
return istestfunction(name)
55+
return istestfunction(obj, name)
4956

5057

5158
class SpecModule(RelaxedMixin, Module):
@@ -120,7 +127,7 @@ def _getobj(self):
120127
if isinstance(value, (types.MethodType, types.FunctionType)):
121128
# If they look like tests, they get skipped; don't want to copy
122129
# tests around!
123-
if istestfunction(name):
130+
if istestfunction(obj, name):
124131
continue
125132
# Non-test == they're probably lifecycle methods
126133
# (setup/teardown) or helpers (_do_thing). Rebind them to the

tests/test_collection.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,24 @@ def actual_nested_test_here(self):
179179
assert "actual test here" in stdout
180180
assert "actual nested test here" in stdout
181181

182+
def test_skips_pytest_fixtures(self, testdir):
183+
testdir.makepyfile(
184+
foo="""
185+
from pytest import fixture
186+
187+
@fixture
188+
def pls_noload():
189+
yield
190+
191+
def actual_test_here():
192+
pass
193+
"""
194+
)
195+
stdout = testdir.runpytest("-v").stdout.str()
196+
assert "actual test here" in stdout
197+
# will be in stdout as a failure and warning if bug present
198+
assert "pls_noload" not in stdout
199+
182200
def test_setup_given_inner_class_instances_when_inherited(self, testdir):
183201
# NOTE: without this functionality in place, we still see setup()
184202
# called on a per-test-method basis, but where 'self' is the outer

0 commit comments

Comments
 (0)