简体   繁体   中英

How to debug failing tests in Django?

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 eg 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?

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)

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.

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM