Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest assert message customization with variable introspection

Tags:

In the pytest documentation it says that you can customize the output message when an assert fails. I want to customize the assert message when testing a REST API method it returns an invalid status code:

def test_api_call(self, client):
    response = client.get(reverse('api:my_api_call'))
    assert response.status_code == 200

So I tried to put a piece of code like this in conftest.py

def pytest_assertrepr_compare(op, left, right):
    if isinstance(left, rest_framework.response.Response):
        return left.json()

But the problem is left is the actual value of response.status_code so it's an int instead of a Response. However the default output messages throws something like:

E assert 400 == 201 E + where 400 = .status_code

Saying that the error 400 comes from an attribute status_code of a object Response.

My point is that there is a kind of introspection of the variable being evaluated. So, how can I customize the assert error message in a comfortable way to get a similar output to example posted above?

like image 948
Marc Tudurí Avatar asked Jun 13 '17 12:06

Marc Tudurí


People also ask

How do you use assertTrue in pytest?

assertTrue() in Python is a unittest library function that is used in unit testing to compare test value with true. This function will take two parameters as input and return a boolean value depending upon the assert condition. If test value is true then assertTrue() will return true else return false.

How do you fix assertion errors?

In order to handle the assertion error, we need to declare the assertion statement in the try block and catch the assertion error in the catch block.


1 Answers

you could use Python built-in capability to show custom exception message:

assert response.status_code == 200, f"My custom msg: actual status code {response.status_code}"

Or you can built a helper assert functions:

def assert_status(response, status=200):  # you can assert other status codes too
    assert response.status_code == status, \
        f"Expected {status}. Actual status {response.status_code}. Response text {response.text}"

# here is how you'd use it
def test_api_call(self, client):
    response = client.get(reverse('api:my_api_call'))
    assert_status(response)

also checkout: https://wiki.python.org/moin/UsingAssertionsEffectively

like image 107
Dmitry Tokarev Avatar answered Sep 16 '22 21:09

Dmitry Tokarev