Answers:
测试这些事情的最佳方法-从命令本身提取所需的功能到独立的函数或类。它有助于从“命令执行内容”中提取内容并编写测试,而无其他要求。
但是,如果由于某种原因无法将逻辑形式的命令解耦,则可以使用如下的call_command方法从任何代码中调用它:
from django.core.management import call_command
call_command('my_command', 'foo', bar='baz')
call_command('check')
,以确保在测试中通过系统检查。
除了执行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)
call_command
需要将经过测试的应用程序加载到中INSTALLED_APPS
。在仅出于测试目的而加载应用程序和使用它之间,我选择了此方法。
call_command
这可能是大多数人应该首先尝试的。这个答案帮助我解决了需要将unicode表名传递给inspectdb
命令的问题。python / bash将命令行参数args解释为ascii,这get_table_description
在django的深处轰炸了这一电话。
以下代码:
from django.core.management import call_command
call_command('collectstatic', verbosity=3, interactive=False)
call_command('migrate', 'myapp', verbosity=3, interactive=False)
...等于在终端中键入以下命令:
$ ./manage.py collectstatic --noinput -v 3
$ ./manage.py migrate myapp --noinput -v 3
关于call_command的Django文档未提及out
必须将其重定向到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())
基于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,它将为您解决问题。它不是很完美-并且还没有管道输出-但它将使用测试数据库。然后,您可以测试数据库效果。
我确信使用Micheal Foords模拟模块并在测试过程中重新连接stdout意味着您也可以从该技术中获得更多帮助-测试输出,退出条件等。