Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent pytest.raises from expecting an exception #5165

Closed
tucked opened this issue Apr 24, 2019 · 6 comments
Closed

Prevent pytest.raises from expecting an exception #5165

tucked opened this issue Apr 24, 2019 · 6 comments
Labels
type: enhancement new feature or API change, should be merged into features branch

Comments

@tucked
Copy link

tucked commented Apr 24, 2019

Here is an example of a case where it would be really handy to be able to tell pytest.raises not to expect an exception:

@pytest.mark.parametrize(
    'exception_for_object',
    [
        SomeError, some_obj1,
        OtherError, some_obj2,
        (), some_obj3,  # does not raise an exception
    ],
)
def test_thing(exception_for_object):
    exception, obj = exception_for_object
    with pytest.raises(exception):
        obj.thing()

The result, though, is this:

>           obj.thing()
E           Failed: DID NOT RAISE ()

This behavior is not useful because obj.thing couldn't raise () anyway:

>>> raise ()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exceptions must derive from BaseException

Not even in Python 2:

>>> raise ()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exceptions must be old-style classes or derived from BaseException, not tuple
Note that None doesn't work instead of ().
>           obj.thing()
E           TypeError: issubclass() arg 2 must be a class or tuple of classes

followed by

>           obj.thing()
E           Failed: DID NOT RAISE None

Tox dump of pip list (running on CentOS 7.6.1810):

atomicwrites==1.3.0,attrs==19.1.0,certifi==2019.3.9,chardet==3.0.4,coverage==4.5.3,funcsigs==1.0.2,future==0.16.0,idna==2.8,isi-sdk-7-2==0.2.5,isi-sdk-8-0==0.2.5,isi-sdk-8-0-1==0.2.5,isi-sdk-8-1-0==0.2.5,isi-sdk-8-1-1==0.2.5,isilon-hadoop-tools==2.0.0,mock==2.0.0,more-itertools==5.0.0,pathlib2==2.3.3,pbr==5.1.3,pluggy==0.9.0,py==1.8.0,pytest==4.3.1,pytest-cov==2.6.1,pytest-randomly==1.2.3,python-dateutil==2.8.0,python-kadmin==0.1.2,python-kadmin-local==0.1.2,requests==2.21.0,scandir==1.10.0,six==1.12.0,urllib3==1.21.1
@tucked
Copy link
Author

tucked commented Apr 24, 2019

Here's a workaround:

def test_thing(exception_for_object):
    exception, obj = exception_for_object
    try:
        obj.thing()
    except exception:
        pass
    else:
        assert not exception

@blueyed
Copy link
Contributor

blueyed commented Apr 25, 2019

Why not:

def test_thing(exception_for_object):
    exception, obj = exception_for_object
    if exception:
        with pytest.raises(exception):
            obj.thing()
    else:
        obj.thing()

But check out also https://github.com/blueyed/pytest/blob/253415cf397fd3d73d0dac0478d27075bdcea1f6/doc/en/example/parametrize.rst#parametrizing-conditional-raising

@blueyed
Copy link
Contributor

blueyed commented Apr 25, 2019

However, I can see that pytest.raises(False) (or better None I guess) would be nice to have.

@blueyed blueyed added the type: enhancement new feature or API change, should be merged into features branch label Apr 25, 2019
@tucked
Copy link
Author

tucked commented Apr 25, 2019

@blueyed I try to avoid splitting tests like that in favor of just having 2 tests. That link is pretty cool, though! Hadn't thought of that...

@RonnyPfannschmidt
Copy link
Member

Im on mobile, bit this has been discussed before, use a different context manager

@asottile
Copy link
Member

#1830 #4324 #4682

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement new feature or API change, should be merged into features branch
Projects
None yet
Development

No branches or pull requests

4 participants