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.
Following up on @Matthijs answer, you can extend the
setup_test_environment
method similar to how theDiscoveryRunner
handles the debug-mode. It changes the value ofsettings.DEBUG
which can be used in your tests by importingdjango.conf.settings
. But you can also add your own settings:In the test you can then simply access the option via the settings
As an alternative way to
manage.py test -a do_this
you can use specific settings fileand define in this file whatever you want.
If you need really dynamic options, maybe you can use
sys.argv
intest_settings.py
, but it is a really dirty hack.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, mymanage.py
file now looks something like this:argparse
is a really nice library with lots of features. There's a good tutorial on it in the Python docs.Django allows adding custom commandline options from the testrunner class. You can create a subclass of the default testrunner class and add your own options, and then let django use your custom testrunner as follows.
For example, create a testrunner.py in your Django project directory, containing:
This is a testrunner that derives from the default runner (so it works just like the default), except that it tells django to add an extra commandline option (in the
add_arguments()
class method) and processes the value of this extra option in the constructor. To run with this new runner, pass its name as follows:Of course you can put this class anywhere else, as long as you pass the full import name to it on the commandline.
Note that you must use
--testrunner=foo
, you cannot use two separate arguments (--testrunner foo
), since then the extra arguments do not work. A fix is pending: https://github.com/django/django/pull/10307This example just prints the option value, but you'll want to pass it to your testcase somehow. I couldn't find any quick info on how to pass options to unittest testcases, but you could probably just use a global (module level) variable or class variable for this (which is not so re-entrant and elegant, but is easy and works).
i'm using environment variables workaround in my project (works in unix-like shells only)
in your module read this value using