Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# Testing warnings

Testfixtures has tools that make it easy to make assertions about code that may emit warnings.

## The `ShouldWarn` context manager

This context manager allows you to assert that particular warnings are emitted in a block of code, for example:

    >>> from warnings import warn
    >>> from testfixtures import ShouldWarn
    >>> with ShouldWarn(UserWarning('you should fix that')):
    ...     warn('you should fix that')

If a warning issued doesn’t match the one expected, `ShouldWarn` will raise an `AssertionError` causing the test in which it occurs to fail:

    >>> from warnings import warn
    >>> from testfixtures import ShouldWarn
    >>> with ShouldWarn(UserWarning('you should fix that')):
    ...     warn("sorry dave, I can't let you do that")
    Traceback (most recent call last):
    ...
    AssertionError:...
    <SequenceComparison(ordered=True, partial=False)(failed)>
    same:
    []

    expected:
    [
    <C:....UserWarning(failed)>
    attributes differ:
    'args': ('you should fix that',) (Comparison) != ("sorry dave, I can't let you do that",) (actual)
    </C:....UserWarning>]

    actual:
    [UserWarning("sorry dave, I can't let you do that"...)]
    </SequenceComparison(ordered=True, partial=False)> (expected) != [UserWarning("sorry dave, I can't let you do that"...)] (actual)

You can check multiple warnings in a particular piece of code:

    >>> from warnings import warn
    >>> from testfixtures import ShouldWarn
    >>> with ShouldWarn(UserWarning('you should fix that'),
    ...                 UserWarning('and that too')):
    ...     warn('you should fix that')
    ...     warn('and that too')

If you don’t care about the order of issued warnings, you can use `order_matters=False`:

    >>> from warnings import warn
    >>> from testfixtures import ShouldWarn
    >>> with ShouldWarn(UserWarning('you should fix that'),
    ...                 UserWarning('and that too'),
    ...                 order_matters=False):
    ...     warn('and that too')
    ...     warn('you should fix that')

If you want to inspect more details of the warnings issued, you can capture them into a list as follows:

    >>> from warnings import warn_explicit
    >>> from testfixtures import ShouldWarn
    >>> with ShouldWarn() as captured:
    ...     warn_explicit(message='foo', category=DeprecationWarning,
    ...                   filename='bar.py', lineno=42)
    >>> len(captured)
    1
    >>> captured[0].message
    DeprecationWarning('foo'...)
    >>> captured[0].lineno
    42

## The `ShouldNotWarn` context manager

If you do not expect any warnings to be logged in a piece of code, you can use the `ShouldNotWarn` context manager. If any warnings are issued in the context it manages, it will raise an `AssertionError` to indicate this:

    >>> from warnings import warn
    >>> from testfixtures import ShouldNotWarn
    >>> with ShouldNotWarn():
    ...     warn("woah dude")
    Traceback (most recent call last):
    ...
    AssertionError:...
    <SequenceComparison(ordered=True, partial=False)(failed)>
    same:
    []

    expected:
    []

    actual:
    [UserWarning('woah dude'...)]
    </SequenceComparison(ordered=True, partial=False)> (expected) != [UserWarning('woah dude'...)] (actual)