Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何直接从测试驱动程序调用自定义Django manage.py命令?_Django_Unit Testing - Fatal编程技术网

如何直接从测试驱动程序调用自定义Django manage.py命令?

如何直接从测试驱动程序调用自定义Django manage.py命令?,django,unit-testing,Django,Unit Testing,我想为Django manage.py命令编写一个单元测试,该命令在数据库表上执行后端操作。如何直接从代码中调用管理命令 我不想从tests.py在操作系统的shell上执行命令,因为我无法使用使用manage.py test(测试数据库、测试虚拟电子邮件发件箱等)设置的测试环境。测试这些东西的最佳方法-将所需的功能从命令本身提取到独立的函数或类。它有助于从“命令执行材料”中抽象出来并编写测试,而无需额外的需求 但如果由于某种原因无法将逻辑表单命令解耦,则可以使用以下方法从任何代码中调用该命令:

我想为Django manage.py命令编写一个单元测试,该命令在数据库表上执行后端操作。如何直接从代码中调用管理命令


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

测试这些东西的最佳方法-将所需的功能从命令本身提取到独立的函数或类。它有助于从“命令执行材料”中抽象出来并编写测试,而无需额外的需求

但如果由于某种原因无法将逻辑表单命令解耦,则可以使用以下方法从任何代码中调用该命令:

from django.core.management import call_command

call_command('my_command', 'foo', bar='baz')

您可以通过执行以下操作来运行任务,而不是执行call_命令技巧:

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)

根据内特的回答,我有以下几点:

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")
这里的优点是,如果您使用了其他选项和optpass,这将为您解决问题。它不是很完美——它还没有管道输出——但它将使用测试数据库。然后可以测试数据库效果

我相信,在测试期间使用Micheal Foords模拟模块并重新布线stdout,也意味着您可以从这项技术中获得更多信息-测试输出、退出条件等。

以下代码:

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
请参阅。

未能提及必须将
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())

+1将可测试逻辑放在其他地方(模型方法?管理器方法?独立函数?),这样您就根本不需要干扰call_命令机制。也使功能更易于重用。即使您提取了逻辑,此函数仍然有助于测试命令特定的行为,如所需的参数,并确保它调用库函数,从而完成真正的工作。开头一段适用于任何边界情况。将您自己的业务逻辑代码从约束为与某个对象(如用户)接口的代码中移出。但是,如果您编写代码行,它可能有一个bug,因此测试确实应该到达任何边界之后。我认为这对于像
call\u命令('check')
这样的东西仍然有用,以确保在测试中通过系统检查。当call\u命令还提供捕获stdin、stdout、stderr时,您为什么要这样做?当文档指定了正确的方法时,这是一个非常好的问题。三年前也许我会给你一个答案;)同样,内特-当他的答案是我一年半前发现的时-我只是在它的基础上建立起来…后期挖掘,但今天这帮助了我:我并不总是使用我的代码库的所有应用程序(取决于使用的Django站点),而且
call\u命令
需要将测试过的应用程序加载到
已安装的应用程序
。在为了测试目的加载应用程序和使用它之间,我选择了这个。
call\u命令
可能是大多数人应该首先尝试的。这个答案帮助我解决了一个需要将unicode表名传递给
inspectdb
命令的问题。python/bash将命令行参数解释为ascii,这在django中将
get\u table\u description
调用炸得很深。为什么不使用call\u命令而麻烦重重呢?