Django has a nice feature for exploring the environment in which the tests
run via the testserver
command. You can give it paths to fixture files used
in the test case you want and go crazy.
However, this use case becomes really unpleasant once you need to load bigger number of fixtures. It would be much more user friendly if you could instead tell it what test case you want to explore and the script automatically inferred what fixtures to load.
The --help
output is silent on this, so let’s roll our own solution
to this. The script will have two mandatory arguments: module
containing the tests and the actual test case name.
run-test-server.py myapp.tests MyComplicatedTestCase
The first idea how to proceed is to simply import the module and look at
fixtures
attribute of the test case. Sadly, it is not that easy. Importing
the module fails with ImproperlyConfiguredException
because simply importing
a module would be too much to ask for without loading all the Django
settings. This could be a whole other rant.
Since __import__
is slightly more complicated that necessary, let’s offload
the actual importing to importlib.import_module
which works exactly as
expected. However, it is only available since Python 2.7.
Once the module is imported, all that needs to be done is to retrieve
the test case, its fixtures and fire out the testserver
command with
appropriate arguments.
The whole script looks as follows. The only unexplained part is the modification of path. This needs to be done so that the script can be located anywhere and still manage to import modules from current directory.
#! /usr/bin/env python
import argparse
from subprocess import call
import sys
import importlib
from django.conf import settings
def get_fixtures(module, case):
settings.configure()= module.split('.')
parts
= importlib.import_module(module)
app return getattr(app, case).fixtures
def main():
= argparse.ArgumentParser()
parser 'MODULE', type=str)
parser.add_argument('TEST_CASE', type=str)
parser.add_argument(
= parser.parse_args()
args = get_fixtures(args.MODULE, args.TEST_CASE)
fixtures
"python", "manage.py", "testserver"] + fixtures)
call([
if __name__ == '__main__':
'.')
sys.path.append( main()
Further improvements
This script could obviously use a bit more polish:
- The help output could be more helpful.
- If something breaks, the user is presented with a stack trace. Not nice.