Search code examples
pythonpython-requests

Python Requests: assert status_code is not failing


I'm trying to fail a test with a specific error message if an api call returns a 403 code. I've tried a couple options:

if int(addresses.status_code) is 403:
    fail("Auth Error: Missing Role {}".format(response.json()))

assert addresses.status_code is not 403

assert addresses.status_code is not codes.forbidden

assert addresses.status_code is codes.ok

The only one of these that is failing is the last, assert addresses.status_code is codes.ok. However, the status code the api call is responding with is 403. I've played around with making sure the types are the same, etc, but not sure where else to go.

How do I test that the status_code is not a specific value?


Solution

  • is tests for identity. The status code is indeed not the same object as 403 or codes.forbidden. The status value is an integer, not a singleton enumeration object.

    Use == to test if the value is the same:

    if addresses.status_code == 403:
        # ...
    
    assert addresses.status_code != 403
    assert addresses.status_code != codes.forbidden
    assert addresses.status_code == codes.ok
    

    or just use

    addresses.raise_for_status()  # raises an exception if not 1xx, 2xx or 3xx
    

    The Response.raise_for_status() method raises a requests.exceptions.HTTPError exception (a subclass of requests.exceptions.RequestException, in turn a OSError subclass).

    Note that sometimes is will work with integers, or any number of other types. But unless there is specific documentation that you can use identity tests, you have instead found an implementation detail where Python will have re-used objects for performance reasons. Such is the case for small integers (from -5 through to 256), and for strings in certain cases, and many other corner cases. So address.status_code is 200 just happens to work in current CPython interpreters, but this is not a given and should not be relied upon.