我怎样才能直接从testing驱动程序调用一个自定义的Django manage.py命令?

我想为Django manage.py命令编写一个unit testing,在数据库表上执行后端操作。 我将如何直接从代码调用pipe理命令?

我不想在tests.py的操作系统的shell上执行命令,因为我不能使用使用manage.py test(testing数据库,testing虚拟电子邮件发件箱等等)设置的testing环境。

testing这种事情的最好方法是从命令本身提取所需的function,以独立的function或类。 它有助于从“命令执行的东西”中抽象出来,并且写入testing,而不需要额

但是,如果你由于某种原因不能解耦逻辑forms的命令,你可以从这样的任何代码调用它:

from django.core.management import call_command call_command('my_command', 'foo', bar='baz') 

而不是做call_command技巧,你可以通过执行以下任务来运行你的任务:

 from myapp.management.commands import my_management_task cmd = my_management_task.Command() opts = {} # kwargs for your command -- lets you override stuff for testing... cmd.handle_noargs(**opts) 

下面的代码:

 from django.core.management import call_command call_command('collectstatic', verbosity=3, interactive=False) call_command('migrate', 'myapp', verbosity=3, interactive=False) 

…等于在terminal中键入的以下命令:

 $ ./manage.py collectstatic --noinput -v 3 $ ./manage.py migrate myapp --noinput -v 3 

请参阅从django文档运行pipe理命令 。

关于call_command的Django文档没有提到out必须被redirect到sys.stdout 。 示例代码应为:

 from django.core.management import call_command from django.test import TestCase from django.utils.six import StringIO import sys class ClosepollTest(TestCase): def test_command_output(self): out = StringIO() sys.stdout = out call_command('closepoll', stdout=out) self.assertIn('Expected output', out.getvalue()) 

build立在Nate的答案我有这样的:

 def make_test_wrapper_for(command_module): def _run_cmd_with(*args): """Run the possibly_add_alert command with the supplied arguments""" cmd = command_module.Command() (opts, args) = OptionParser(option_list=cmd.option_list).parse_args(list(args)) cmd.handle(*args, **vars(opts)) return _run_cmd_with 

用法:

 from myapp.management import mycommand cmd_runner = make_test_wrapper_for(mycommand) cmd_runner("foo", "bar") 

这样做的好处是,如果您已经使用了其他选项和OptParse,则会为您sorting。 它并不完美,而且它不会输出输出,但会使用testing数据库。 然后您可以testing数据库效果。

我确定使用Micheal Foords mock模块,并且在testing期间重新连接stdout意味着你可以从这个技术中获得更多 – testing输出,退出条件等。