Merge pull request #4076 from nicoddemus/unittest-param-fixture-msg

Improve error message when TestCase functions use a parametrized fixture
This commit is contained in:
Ronny Pfannschmidt 2018-10-06 07:43:57 +02:00 committed by GitHub
commit 66609665f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 7 deletions

View File

@ -0,0 +1 @@
Improve error message when test functions of ``unittest.TestCase`` subclasses use a parametrized fixture.

View File

@ -564,7 +564,20 @@ class FixtureRequest(FuncargnamesCompatAttr):
except (AttributeError, ValueError): except (AttributeError, ValueError):
param = NOTSET param = NOTSET
param_index = 0 param_index = 0
if fixturedef.params is not None: has_params = fixturedef.params is not None
fixtures_not_supported = getattr(funcitem, "nofuncargs", False)
if has_params and fixtures_not_supported:
msg = (
"{name} does not support fixtures, maybe unittest.TestCase subclass?\n"
"Node id: {nodeid}\n"
"Function type: {typename}"
).format(
name=funcitem.name,
nodeid=funcitem.nodeid,
typename=type(funcitem).__name__,
)
fail(msg)
if has_params:
frame = inspect.stack()[3] frame = inspect.stack()[3]
frameinfo = inspect.getframeinfo(frame[0]) frameinfo = inspect.getframeinfo(frame[0])
source_path = frameinfo.filename source_path = frameinfo.filename
@ -573,9 +586,11 @@ class FixtureRequest(FuncargnamesCompatAttr):
if source_path.relto(funcitem.config.rootdir): if source_path.relto(funcitem.config.rootdir):
source_path = source_path.relto(funcitem.config.rootdir) source_path = source_path.relto(funcitem.config.rootdir)
msg = ( msg = (
"The requested fixture has no parameter defined for the " "The requested fixture has no parameter defined for test:\n"
"current test.\n\nRequested fixture '{}' defined in:\n{}" " {}\n\n"
"Requested fixture '{}' defined in:\n{}"
"\n\nRequested here:\n{}:{}".format( "\n\nRequested here:\n{}:{}".format(
funcitem.nodeid,
fixturedef.argname, fixturedef.argname,
getlocation(fixturedef.func, funcitem.config.rootdir), getlocation(fixturedef.func, funcitem.config.rootdir),
source_path, source_path,

View File

@ -0,0 +1,13 @@
import pytest
import unittest
@pytest.fixture(params=[1, 2])
def two(request):
return request.param
@pytest.mark.usefixtures("two")
class TestSomethingElse(unittest.TestCase):
def test_two(self):
pass

View File

@ -3606,7 +3606,8 @@ class TestParameterizedSubRequest(object):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
E*Failed: The requested fixture has no parameter defined for the current test. E*Failed: The requested fixture has no parameter defined for test:
E* test_call_from_fixture.py::test_foo
E* E*
E*Requested fixture 'fix_with_param' defined in: E*Requested fixture 'fix_with_param' defined in:
E*test_call_from_fixture.py:4 E*test_call_from_fixture.py:4
@ -3632,7 +3633,8 @@ class TestParameterizedSubRequest(object):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
E*Failed: The requested fixture has no parameter defined for the current test. E*Failed: The requested fixture has no parameter defined for test:
E* test_call_from_test.py::test_foo
E* E*
E*Requested fixture 'fix_with_param' defined in: E*Requested fixture 'fix_with_param' defined in:
E*test_call_from_test.py:4 E*test_call_from_test.py:4
@ -3662,7 +3664,8 @@ class TestParameterizedSubRequest(object):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
E*Failed: The requested fixture has no parameter defined for the current test. E*Failed: The requested fixture has no parameter defined for test:
E* test_external_fixture.py::test_foo
E* E*
E*Requested fixture 'fix_with_param' defined in: E*Requested fixture 'fix_with_param' defined in:
E*conftest.py:4 E*conftest.py:4
@ -3705,7 +3708,8 @@ class TestParameterizedSubRequest(object):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
E*Failed: The requested fixture has no parameter defined for the current test. E*Failed: The requested fixture has no parameter defined for test:
E* test_foos.py::test_foo
E* E*
E*Requested fixture 'fix_with_param' defined in: E*Requested fixture 'fix_with_param' defined in:
E*fix.py:4 E*fix.py:4

View File

@ -1010,3 +1010,15 @@ def test_testcase_handles_init_exceptions(testdir):
result = testdir.runpytest() result = testdir.runpytest()
assert "should raise this exception" in result.stdout.str() assert "should raise this exception" in result.stdout.str()
assert "ERROR at teardown of MyTestCase.test_hello" not in result.stdout.str() assert "ERROR at teardown of MyTestCase.test_hello" not in result.stdout.str()
def test_error_message_with_parametrized_fixtures(testdir):
testdir.copy_example("unittest/test_parametrized_fixture_error_message.py")
result = testdir.runpytest()
result.stdout.fnmatch_lines(
[
"*test_two does not support fixtures*",
"*TestSomethingElse::test_two",
"*Function type: TestCaseFunction",
]
)