Is it possible to pass command line arguments to Django's manage.py
script, specifically for unit tests? i.e. if I do something like
manage.py test myapp -a do_this
Can I receive the value do_this
in the setUp
function of unit test?
P.S. @Martin asked the justification for using command line args in tests:
Some extensive tests take a lot of time and don't need to be run before every commit. I want to make them optional.
Occasional debug messages printed by my test cases should be optional
Sometimes I just want the tests to go crazy and try a lot more permutations of data.
All the above would be quite convenient with command line options. Once in a while testing can be a lot more extensive or verbose, otherwise it'll be quick.
I just ran into this problem myself, and I wanted to avoid setting environmental variables on the command line. Environmental variables certainly work, but it's difficult to keep track of which variables have an effect and there's no error message to let you know if you've mistyped one of them.
To get around this I've used argparse
to extract extra parameters to the command-line argument. For example, my manage.py
file now looks something like this:
#!/usr/bin/env python
import os
import sys
import argparse
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
argv = sys.argv
cmd = argv[1] if len(argv) > 1 else None
if cmd in ['test']: # limit the extra arguments to certain commands
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--foo', default='bar')
args, argv = parser.parse_known_args(argv)
# We can save the argument as an environmental variable, in
# which case it's to retrieve from within `project.settings`,
os.environ['FOO'] = args.foo
# or we can save the variable to settings directly if it
# won't otherwise be overridden.
from django.conf import settings
settings.foo = args.foo
from django.core.management import execute_from_command_line
# parse_known_args strips the extra arguments from argv,
# so we can safely pass it to Django.
execute_from_command_line(argv)
argparse
is a really nice library with lots of features. There's a good tutorial on it in the Python docs.