This pattern is from the django docs:
class SimpleTest(unittest.TestCase):
def test_details(self):
client = Client()
response = client.get('/customer/details/')
self.assertEqual(response.status_code, 200)
From: https://docs.djangoproject.com/en/1.8/topics/testing/tools/#default-test-client
If the test fails, the error message does not help very much. For example if the status_code is 302, then I see 302 != 200
.
The question is now: Where does the wrong HTTPResponse get created?
I would like to see the stacktrace of the interpreter where the wrong HTTPResponse object get created.
I read the docs for the assertions of django but found no matching method.
Update
This is a general question: How to see the wanted information immediately if the assertion fails? Since these assertions (self.assertEqual(response.status_code, 200)
) are common, I don't want to start debugging.
Update 2016
I had the same idea again, found the current answer not 100% easy. I wrote a new answer, which has a simple to use solution (subclass of django web client): Django: assertEqual(response.status_code, 200): I want to see useful stack of functions calls
I think it could be achieved by creating a
TestCase
subclass that monkeypatchesdjango.http.response.HttpResponseBase.__init__()
to record a stack trace and store it on theResponse
object, then writing anassertResponseCodeEquals(response, status_code=200)
method that prints the stored stack trace on failure to show where theResponse
was created.I could actually really use a solution for this myself, and might look at implementing it.
Update: Here's a v1 implementation, which could use some refinement (eg only printing relevant lines of the stack trace).
Maybe this could work for you:
Using
@override_settings
to haveDEBUG=True
will have the stacktrace just as if you were running an instance inDEBUG
mode.Secondly, in order to provide the content of the response, you need to either
print
it or log it using thelogging
module, or add it as your message for theassert
method. Without a debugger, once youassert
, it is too late to print anything useful (usually).You can also configure
logging
and add a handler to save messages in memory, and print all of that; either in a custom assert method or in a custom test runner.If the assertion fails, there isn't a traceback. The
client.get()
hasn't failed, it just returned a different response than you were expecting.You could use a pdb to step through the
client.get()
call, and see why it is returning the unexpected response.I was inspired by the solution that @Fush proposed but my code was using assertRedirects which is a longer method and was a bit too much code to duplicate without feeling bad about myself.
I spent a bit of time figuring out how I could just call super() for each assert and came up with this. I've included 2 example assert methods - they would all basically be the same. Maybe some clever soul can think of some metaclass magic that does this for all methods that take 'response' as their first argument.
I subclassed the django web client, to get this:
Usage
Implementation
Conclusion
This results in a long exception if a http response with a wrong status code was created. If you are not afraid of long exceptions, you see very fast the root of the problem. That's what I want, I am happy.
Credits
This was based on other answers of this question.