Reputation: 3574
My team runs a custom test suite pretty regularly. When we want to run the whole thing, we do
./manage.py test --keepdb --failfast --settings=AE.test_settings
When we want to run tests on a specific app, we do the same, but with the app name include.
I'd like to make a custom management command that, when called, will run the default test suite, but append the --keepdb, --failfast, and --settings=AE.test_settings params. Ideally something like
./manage.py aetest
That can also be run with app names, such that
./manage.py aetest registration
Would be the same as running
./manage.py test registration --keepdb --failfast --settings=AE.test_settings
My attempt so far is
from django.core.management.base import BaseCommand, CommandError
from django.core import management
class Command(BaseCommand):
def handle(self, *args, **kwargs):
positional_arguments = [
'--keepdb',
'--failfast',
'--settings=NJ.test_settings',
]
for item in args:
positional_arguments.append(item)
keyword_arguments = {
'settings': "AE.test_setings",
}
keyword_arguments.update(kwargs)
management.call_command("test", *positional_arguments, **keyword_arguments)
If I try to pass further positional arguments, my command errors out in such a way as to imply they were never passed. And the keyword argument never makes it to the call_command (the command runs with my default settings.py file)
Any idea how I can have this management command accept additional positional and keyword parameters, but append the desired ones automatically?
Thanks!
UPDATE
I was given the great idea of subclassing BaseTestCommand. While this seems to work for True/False variables, passing the settings variable doesn't seem to work. If I use the following code:
class Command(BaseTestCommand):
def handle(self, *test_labels, **options):
options['failfast'] = True
options['keepdb'] = True
options['settings'] = "AE.test_settings"
print(options)
super(Command, self).handle(*test_labels, **options)
Running my new command uses the failfast and the keepdb, but it still uses the default settings.py for my project. Any idea why this might be?
Side note: running the new command with --settings=AE.test_settings works like a charm
Upvotes: 1
Views: 1910
Reputation: 5574
You could subclass the Django test
command and override the handle
method to set the options you need.
from django.core.management.commands.test import Command as BaseTestCommand
class Command(BaseTestCommand):
def handle(self, *test_labels, **options):
options['failfast'] = True
options['keepdb'] = True
options['settings'] = 'NJ.test_settings'
super(Command, self).handle(*test_labels, **options)
As to why your code does not work, it is because your are misusing the call_command
function. Every command option (that starts with --
) must be passed as a keyworded argument even if it is boolean, your handle
method should then be:
def handle(self, *args, **kwargs):
kwargs.update({
'settings': 'NJ.test_settings',
'keepdb': True,
'failfast': True
})
management.call_command("test", *args, **kwargs)
Upvotes: 4