Reputation: 3211
How do I debug my tests? For example, I POST to create an entry and expect it to validate and return a particular page. It works in the browser and in the shell, but the test is the only thing that fails (ironically!). I would like to print the response to the console or something so I could read errors or what have you. But I can only see things that I print
in e.g. the view.
Not sure it's necessary, but here's the test code in question from tests.py
:
resp = self.client.post('/meal/invite/',
{'summary': 'Test munch', 'when': now(), 'max_diners': '1', 'description': 'Munchies'}, follow=True)
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, 'Test munch', 1)
self.assertContains(resp, 'You are hosting this meal', 1)
The final assertion is incorrect. If I change it to a value present in the original form page showing 'field required' errors, it passes. I just can't see what I'm missing.
I have a few other tests working, but I just don't know how to debug this.
How is it done?
Upvotes: 29
Views: 23627
Reputation: 91
Django by default sets DEBUG
to False
when running tests to emulate a production environment and get better performance.
When your tests fail and you don't know why (except a nice HTTP 4xx, 5xx status code) that essentially tells you nothing you can set DEBUG
to True
.
To do that, run the tests with the debug-mode
flag like this:
python manage.py test --debug-mode
Source: How do you set DEBUG to True when running a Django test?
Upvotes: 1
Reputation: 1
in pycharm you can put a test in tests.py using TestCase library then highlight that test and then rt click to get the option to runtests.tests in debug mode. Very convenient and puts making unit tests in my regular development cycle.
Upvotes: 0
Reputation: 14234
If you are using vscode, you can create a new configuration inside your root/vscode/launch.json file like so:
{
"version": "0.2.0",
"configurations": [
{
"name": "Django RUN",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": [
"runserver",
"--noreload",
"--nothreading"
],
"django": true
},
{
"name": "Django TEST",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": [
"test",
"<your-app-name>",
],
"django": true
}
]
}
This allows you to put breakpoints in your tests and debug using vscode.
Upvotes: 15
Reputation: 806
One can use eclipse IDE with Pydev, create a Debug configuration where the Arguments are the test command. Something like:
test users.tests.selenium_tests.UsersTestCase.test_user_creation --keepdb --settings=project.settings.test_settings
And then, use the Pydev debugger with breakpoints and step by step workflow, variables, expressions, etc.
The docs are here (http://www.pydev.org/manual_adv_debugger.html) but don't refer to Django.
Upvotes: 0
Reputation: 1485
To run the test under pdb:
python -m pdb manage.py test yourapp
I agree with Alasdair, the print response.content (and printing stuff in general) is a great help. The output gets mixed up with the normal test runner output, and should be removed once you find the problem and fix it, but it can help you narrow down the problem.
Also, if the code works in the browser and the shell but not the unit test, remember that the unit test makes a new (empty) database. Ensure that your setUp puts in any data that is required for your test.
(Updated the code part from Patrick's suggestion, thanks Patrick)
Upvotes: 16
Reputation: 55972
You can drop in a pdb
and inspect everything.
If you're using nose
i believe you have to run your tests with -s
-s, --nocapture Don't capture stdout (any stdout output will be
printed immediately) [NOSE_NOCAPTURE]
This is what keeps you from seeing output immediately.
Upvotes: 13
Reputation: 309099
The simplest thing to do is add print response.content
before your assertion. The output can be a little overwhelming, but often its enough to let you spot the problem.
If that doesn't solve it, there are loads of features listed in the docs which can help. Add a few print statements and see what you get. Here's a few suggestions, but don't limit yourself to these, there are more tools in the docs.
https://docs.djangoproject.com/en/dev/topics/testing/
First, you need to check that the page is actually redirecting as you expect. Try using redirect_chain
or assertRedirects
.
I suspect that your post data is not valid for some reason. You can grab the form from the response context.
form = response.context['form']
print form.is_valid()
print form.errors
Upvotes: 7