Skip to content

Commit 212937e

Browse files
committed
Improve error message when TestCase functions use a parametrized fixture
Fix pytest-dev#2535
1 parent e712adc commit 212937e

File tree

5 files changed

+52
-7
lines changed

5 files changed

+52
-7
lines changed

changelog/2535.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve error message when test functions of ``unittest.TestCase`` subclasses use a parametrized fixture.

src/_pytest/fixtures.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,20 @@ def _compute_fixture_value(self, fixturedef):
562562
except (AttributeError, ValueError):
563563
param = NOTSET
564564
param_index = 0
565-
if fixturedef.params is not None:
565+
has_params = fixturedef.params is not None
566+
fixtures_not_supported = getattr(funcitem, "nofuncargs", False)
567+
if has_params and fixtures_not_supported:
568+
msg = (
569+
"{name} does not support fixtures, maybe unittest.TestCase subclass?\n"
570+
"Node id: {nodeid}\n"
571+
"Function type: {typename}"
572+
).format(
573+
name=funcitem.name,
574+
nodeid=funcitem.nodeid,
575+
typename=type(funcitem).__name__,
576+
)
577+
fail(msg)
578+
if has_params:
566579
frame = inspect.stack()[3]
567580
frameinfo = inspect.getframeinfo(frame[0])
568581
source_path = frameinfo.filename
@@ -571,9 +584,11 @@ def _compute_fixture_value(self, fixturedef):
571584
if source_path.relto(funcitem.config.rootdir):
572585
source_path = source_path.relto(funcitem.config.rootdir)
573586
msg = (
574-
"The requested fixture has no parameter defined for the "
575-
"current test.\n\nRequested fixture '{}' defined in:\n{}"
587+
"The requested fixture has no parameter defined for test:\n"
588+
" {}\n\n"
589+
"Requested fixture '{}' defined in:\n{}"
576590
"\n\nRequested here:\n{}:{}".format(
591+
funcitem.nodeid,
577592
fixturedef.argname,
578593
getlocation(fixturedef.func, funcitem.config.rootdir),
579594
source_path,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
import unittest
3+
4+
5+
@pytest.fixture(params=[1, 2])
6+
def two(request):
7+
return request.param
8+
9+
10+
@pytest.mark.usefixtures("two")
11+
class TestSomethingElse(unittest.TestCase):
12+
def test_two(self):
13+
pass

testing/python/fixture.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3600,7 +3600,8 @@ def test_foo(request, get_named_fixture):
36003600
result = testdir.runpytest()
36013601
result.stdout.fnmatch_lines(
36023602
"""
3603-
E*Failed: The requested fixture has no parameter defined for the current test.
3603+
E*Failed: The requested fixture has no parameter defined for test:
3604+
E* test_call_from_fixture.py::test_foo
36043605
E*
36053606
E*Requested fixture 'fix_with_param' defined in:
36063607
E*test_call_from_fixture.py:4
@@ -3626,7 +3627,8 @@ def test_foo(request):
36263627
result = testdir.runpytest()
36273628
result.stdout.fnmatch_lines(
36283629
"""
3629-
E*Failed: The requested fixture has no parameter defined for the current test.
3630+
E*Failed: The requested fixture has no parameter defined for test:
3631+
E* test_call_from_test.py::test_foo
36303632
E*
36313633
E*Requested fixture 'fix_with_param' defined in:
36323634
E*test_call_from_test.py:4
@@ -3656,7 +3658,8 @@ def test_foo(request):
36563658
result = testdir.runpytest()
36573659
result.stdout.fnmatch_lines(
36583660
"""
3659-
E*Failed: The requested fixture has no parameter defined for the current test.
3661+
E*Failed: The requested fixture has no parameter defined for test:
3662+
E* test_external_fixture.py::test_foo
36603663
E*
36613664
E*Requested fixture 'fix_with_param' defined in:
36623665
E*conftest.py:4
@@ -3699,7 +3702,8 @@ def test_foo(request):
36993702
result = testdir.runpytest()
37003703
result.stdout.fnmatch_lines(
37013704
"""
3702-
E*Failed: The requested fixture has no parameter defined for the current test.
3705+
E*Failed: The requested fixture has no parameter defined for test:
3706+
E* test_foos.py::test_foo
37033707
E*
37043708
E*Requested fixture 'fix_with_param' defined in:
37053709
E*fix.py:4

testing/test_unittest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,3 +1010,15 @@ def test_hello(self):
10101010
result = testdir.runpytest()
10111011
assert "should raise this exception" in result.stdout.str()
10121012
assert "ERROR at teardown of MyTestCase.test_hello" not in result.stdout.str()
1013+
1014+
1015+
def test_error_message_with_parametrized_fixtures(testdir):
1016+
testdir.copy_example("unittest/test_parametrized_fixture_error_message.py")
1017+
result = testdir.runpytest()
1018+
result.stdout.fnmatch_lines(
1019+
[
1020+
"*test_two does not support fixtures*",
1021+
"*TestSomethingElse::test_two",
1022+
"*Function type: TestCaseFunction",
1023+
]
1024+
)

0 commit comments

Comments
 (0)