Skip to content
Advertisement

py.test assert may raise, and if it raises it will be __

Is there pytest functionality similar to pytest.raises that passes iff the block raises the specified exception, or doesn’t raise at all? Something like:

JavaScript

This question came up in the following situation..

The function to test:

JavaScript

A couple of simple tests (fixtures below):

JavaScript

The fixtures:

JavaScript

the indicated <== problem is only a problem for test_encode_err() (and not test_encode_u8()), and happens since u''.encode('ascii') doesn’t raise a UnicodeEncodeError (no unicode strings that doesn’t contain characters above code point 127 will raise).

Is there a py.test function that covers this use case?

Advertisement

Answer

I consider the provided response really incomplete. I like to parametrize tests for functions that could accepts different values.

Consider the following function that only accepts empty strings, in which case returns True. If you pass other type raises a TypeError and if the passed string is not empty a ValueError.

JavaScript

You can conveniently write parametric tests for all cases in a single test in different ways:

JavaScript

Note that when an exception raises inside pytest.raises context, the contexts exits so the later assert ... == expected_result is not executed when the exception is catch. If other exception raises, it is propagated to your test so the comparison is not executed either. This allows you to write more assertions after the execution of the function for successfull calls.

But this can be improved in a convenient maybe_raises fixture, that is what you’re looking for at first:

JavaScript

And the test can be rewritten as:

JavaScript

Really nice, right? Of course you need to know how the magic works to write the test properly, always knowing that the context will exits when the exception is catched.

I think that pytest does not includes this because could be a really confusing pattern that could lead to unexpected false negatives and bad tests writing. Rather than that, pytest documentation encourauges you to pass expectation contexts as parameters but for me this solution looks really ugly.

EDIT: just packaged this fixture, see pytest-maybe-raises.

Advertisement