当您的应用具有测试目录时,在Django中运行特定的测试用例


163

Django文档(http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests)指出,您可以通过指定单个测试用例来运行它们:

$ ./manage.py test animals.AnimalTestCase

假设您将测试保存在Django应用程序的tests.py文件中。如果是这样,那么此命令将按预期工作。

我在tests目录中有针对Django应用程序的测试:

my_project/apps/my_app/
├── __init__.py
├── tests
   ├── __init__.py
   ├── field_tests.py
   ├── storage_tests.py
├── urls.py
├── utils.py
└── views.py

tests/__init__.py文件具有suite()函数:

import unittest

from my_project.apps.my_app.tests import field_tests, storage_tests

def suite():
    tests_loader = unittest.TestLoader().loadTestsFromModule
    test_suites = []
    test_suites.append(tests_loader(field_tests))
    test_suites.append(tests_loader(storage_tests))
    return unittest.TestSuite(test_suites)

要运行测试,请执行以下操作:

$ ./manage.py test my_app

尝试指定单个测试用例会引发异常:

$ ./manage.py test my_app.tests.storage_tests.StorageTestCase
...
ValueError: Test label 'my_app.tests.storage_tests.StorageTestCase' should be of the form app.TestCase or app.TestCase.test_method

我试图做异常消息说:

$ ./manage.py test my_app.StorageTestCase
...
ValueError: Test label 'my_app.StorageTestCase' does not refer to a test

当我的测试位于多个文件中时,如何指定单个测试用例?

Answers:


155

结帐django-nose。它允许您指定测试运行方式:

python manage.py test another.test:TestCase.test_method

或如注释中所述,使用以下语法:

python manage.py test another.test.TestCase.test_method

谢谢@sdolan。遇到与hekevintran相同的问题。切换到django-nose并修复了该问题,也比默认的Django测试运行器好得多。
LeeMobile

这会运行测试,但是如何运行整个TestCase?
jMyles 2012年

5
@jMyles:another.test:TestCase
Sam Dolan

4
请注意像我这样从Stackoverflow中盲目粘贴的人:如果没有提到的插件,这将出错,请使用在Django 1.6+中有效的另一个答案(。代替:)中描述的语法。
安迪·史密斯

1
我不赞成这个答案,因为它实际上没有回答OP的问题,这是如何在Django中做到这一点。相反,它只是建议切换到Nosetest
Josh Brown

175

从Django 1.6开始,您可以对要运行的元素使用完整的点符号来运行完整的测试用例或单个测试。

现在,自动测试发现将在工作目录下以test开头的任何文件中找到测试,因此解决了您必须重命名文件的问题,但是现在您可以将其保留在所需的目录中。如果要使用自定义文件名,则可以使用option标志指定一个模式(默认Django测试运行器)--pattern="my_pattern_*.py"

因此,如果您在manage.py目录中,并且想要在app / module下的文件test_a内的TestCase子类中运行测试,则可以执行以下操作:Atests.pyexample

python manage.py test example.tests.A.test_a

如果您不想在Django 1.6或更高版本中包含依赖项,那么您将采用这种方式。

有关更多信息,请参见Django文档。


很高兴看到现在内置在Django中的此功能。
hekevintran 2014年

我根本无法使用它;error: option --pattern not recognized以及invalid command name
geodesic

这在Django v3中非常有效!
柯克

11

我自己遇到了这个问题,发现了这个问题,以防万一其他人出现,这就是我挖的东西。DjangoTestSuiteRuner使用一种称为build_test(label)的方法,该方法根据标签确定要运行哪些测试用例。研究此方法,结果发现他们正在“模型”或“测试”模块上执行getattr()。这意味着,如果您返回一个套件,则测试运行程序不在该套件中寻找您的测试用例,它只会查找那些模块中的一个。

一个快速的解决方法是__init__.py直接导入测试而不是定义套件。使它们成为“测试”模块的一部分,因此build_test(label)可以找到它们。

对于上面的示例,tests/__init__.py应仅包含:

from field_tests import *
from storage_tests import *

这不是很优雅,当然,如果您要对套件进行一些更复杂的操作,则此方法将无法正常工作,但在这种情况下可以。




3

将此代码放在__init__.py中,它将导入包和子包中的所有测试类。这将允许您运行特定的测试,而无需手动导入每个文件。

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

同样,对于您的测试套件,您可以简单地使用:

def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")

现在,您需要为新测试做的就是编写它们,并确保它们在tests文件夹中。不再需要繁琐的进口维修!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.