diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 45fde880f29..569c6539147 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -66,7 +66,9 @@ * Add ``build/`` and ``dist/`` to the default ``--norecursedirs`` list. Thanks `@mikofski`_ for the report and `@tomviner`_ for the PR (`#1544`_). -* +* pytest.raises in the context manager form accepts a custom + message to raise when no exception occurred. + Thanks `@palaviv`_ for the complete PR (`#1616`_). .. _@milliams: https://github.com/milliams .. _@csaftoiu: https://github.com/csaftoiu @@ -91,6 +93,7 @@ .. _#1520: https://github.com/pytest-dev/pytest/pull/1520 .. _#372: https://github.com/pytest-dev/pytest/issues/372 .. _#1544: https://github.com/pytest-dev/pytest/issues/1544 +.. _#1616: https://github.com/pytest-dev/pytest/pull/1616 **Bug Fixes** diff --git a/_pytest/python.py b/_pytest/python.py index 4262d6fa7f7..526f4be09cb 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1337,6 +1337,16 @@ def raises(expected_exception, *args, **kwargs): >>> with raises(ZeroDivisionError): ... 1/0 + .. versionchanged:: 2.10 + + In the context manager form you may use the keyword argument + ``message`` to specify a custom failure message:: + + >>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): + ... pass + ... Failed: Expecting ZeroDivisionError + + .. note:: When using ``pytest.raises`` as a context manager, it's worthwhile to @@ -1412,8 +1422,12 @@ def raises(expected_exception, *args, **kwargs): elif not isclass(expected_exception): raise TypeError(msg % type(expected_exception)) + message = "DID NOT RAISE {0}".format(expected_exception) + if not args: - return RaisesContext(expected_exception) + if "message" in kwargs: + message = kwargs.pop("message") + return RaisesContext(expected_exception, message) elif isinstance(args[0], str): code, = args assert isinstance(code, str) @@ -1434,11 +1448,12 @@ def raises(expected_exception, *args, **kwargs): func(*args[1:], **kwargs) except expected_exception: return _pytest._code.ExceptionInfo() - pytest.fail("DID NOT RAISE {0}".format(expected_exception)) + pytest.fail(message) class RaisesContext(object): - def __init__(self, expected_exception): + def __init__(self, expected_exception, message): self.expected_exception = expected_exception + self.message = message self.excinfo = None def __enter__(self): @@ -1448,7 +1463,7 @@ def __enter__(self): def __exit__(self, *tp): __tracebackhide__ = True if tp[0] is None: - pytest.fail("DID NOT RAISE") + pytest.fail(self.message) if sys.version_info < (2, 7): # py26: on __exit__() exc_value often does not contain the # exception value. diff --git a/doc/en/assert.rst b/doc/en/assert.rst index 680d2279805..d867dfa9af6 100644 --- a/doc/en/assert.rst +++ b/doc/en/assert.rst @@ -85,6 +85,15 @@ and if you need to have access to the actual exception info you may use:: the actual exception raised. The main attributes of interest are ``.type``, ``.value`` and ``.traceback``. +.. versionchanged:: 2.10 + +In the context manager form you may use the keyword argument +``message`` to specify a custom failure message:: + + >>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): + ... pass + ... Failed: Expecting ZeroDivisionError + If you want to write test code that works on Python 2.4 as well, you may also use two other ways to test for an expected exception:: diff --git a/testing/python/raises.py b/testing/python/raises.py index 0ea7f9bee3e..93295966c7b 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -76,3 +76,23 @@ def test_no_raise_message(self): pytest.raises(ValueError, int, '0') except pytest.raises.Exception as e: assert e.msg == "DID NOT RAISE {0}".format(repr(ValueError)) + else: + assert False, "Expected pytest.raises.Exception" + + try: + with pytest.raises(ValueError): + pass + except pytest.raises.Exception as e: + assert e.msg == "DID NOT RAISE {0}".format(repr(ValueError)) + else: + assert False, "Expected pytest.raises.Exception" + + def test_costum_raise_message(self): + message = "TEST_MESSAGE" + try: + with pytest.raises(ValueError, message=message): + pass + except pytest.raises.Exception as e: + assert e.msg == message + else: + assert False, "Expected pytest.raises.Exception"