Mike Slinn
Mike Slinn

Django Unit Tests

Published 2021-03-27.
Time to read: about 2 minutes.

This article is categorized under Django, Django-Oscar, Visual Studio Code.

This post provides:

  1. A listing of information sources pertaining to Django and django-oscar unit tests.
  2. Help information about the manage.py test subcommand.
  3. Comments about testing a django-oscar webapp.

Information Sources

manage.py test Subcommand

Here is the help information:

Shell
(oscar) $ ./manage.py test -h
  usage: manage.py test [-h] [--noinput] [--failfast] [--testrunner TESTRUNNER] [-t TOP_LEVEL] [-p PATTERN] [--keepdb]
                        [-r] [--debug-mode] [-d] [--parallel [N]] [--tag TAGS] [--exclude-tag EXCLUDE_TAGS] [--pdb] [-b]
                        [-k TEST_NAME_PATTERNS] [--version] [-v {0,1,2,3}] [--settings SETTINGS]
                        [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]
                        [test_label [test_label ...]]

  Discover and run tests in the specified modules or the current directory.

  positional arguments:
    test_label            Module paths to test; can be modulename, modulename.TestCase or
                          modulename.TestCase.test_method

  optional arguments:
    -h, --help            show this help message and exit
    --noinput, --no-input
                          Tells Django to NOT prompt the user for input of any kind.
    --failfast            Tells Django to stop running the test suite after first failed test.
    --testrunner TESTRUNNER
                          Tells Django to use specified test runner class instead of the one specified by the
                          TEST_RUNNER setting.
    -t TOP_LEVEL, --top-level-directory TOP_LEVEL
                          Top level of project for unittest discovery.
    -p PATTERN, --pattern PATTERN
                          The test matching pattern. Defaults to test*.py.
    --keepdb              Preserves the test DB between runs.
    -r, --reverse         Reverses test cases order.
    --debug-mode          Sets settings.DEBUG to True.
    -d, --debug-sql       Prints logged SQL queries on failure.
    --parallel [N]        Run tests using up to N parallel processes.
    --tag TAGS            Run only tests with the specified tag. Can be used multiple times.
    --exclude-tag EXCLUDE_TAGS
                          Do not run tests with the specified tag. Can be used multiple times.
    --pdb                 Runs a debugger (pdb, or ipdb if installed) on error or failure.
    -b, --buffer          Discard output from passing tests.
    -k TEST_NAME_PATTERNS
                          Only run test methods and classes that match the pattern or substring. Can be used multiple
                          times. Same as unittest -k option.
    --version             show program's version number and exit
    -v {0,1,2,3}, --verbosity {0,1,2,3}
                          Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
    --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided,
                          the DJANGO_SETTINGS_MODULE environment variable will be used.
    --pythonpath PYTHONPATH
                          A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
    --traceback           Raise on CommandError exceptions
    --no-color            Don't colorize the command output.
    --force-color         Force colorization of the command output.

You can read about the manage.py test subcommand options.

Running Django Tests

Running tests for the first time takes a while to create the test database. The test framework looks up the name of the production database from Django settings and prepends test_ to the name, then creates the database.

My production database was defined in settings/base.py as ancient_warmth, so the test database was automatically called test_ancient_warmth. You can launch tests from the command line like this:

Shell
(oscar) $ ./manage.py test --noinput
Creating test database for alias 'default'...
System check identified no issues (0 silenced).

... test output might occur here...

Ran 1 test in 40.325s

OK
Destroying test database for alias 'default'...

The test database is not deleted after the unit tests run. The next time you run tests, you will see this message:

Got an error creating the test database: database "test_ancient_warmth" already exists

Type 'yes' if you would like to try deleting the test database 'test_ancient_warmth', or 'no' to cancel:

The --noinput option shown on the command line above automatically answers yes to manage.py prompts. Alternatively, providing the --keepdb option preserves the test database and its contents between tests.

Visual Studio Code Launch Configurations

Below are 3 Microsoft Visual Studio Code launch configurations. The file containing the definitions of the launch configurations (.vscode/launch.json) should be placed in the top-level directory of your Django webapp.

  1. For running and debugging the application.
  2. (Highlighted) for running and debugging all unit tests, while reusing the test database.
  3. For running and debugging all unit tests with a fresh test database each time.
.vscode/launch.json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "justMyCode": false,
      "name": "Ancient Warmth / Django-Oscar",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/manage.py",
      "python": "${env:oscar}/bin/python",
      "args": [
        "runserver",
        "--noreload",
        "0.0.0.0:8001",
      ],
      "django": true
    },
    {
      "justMyCode": true,
      "name": "Ancient Warmth tests / keep DB",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/manage.py",
      "python": "${env:oscar}/bin/python",
      "args": [
        "test",
        "--keepdb",
      ],
      "django": true
    },
    {
      "justMyCode": true,
      "name": "Ancient Warmth tests / recreate DB",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/manage.py",
      "python": "${env:oscar}/bin/python",
      "args": [
        "test",
        "--noinput"
      ],
      "django": true
    },
  ]
}