如何在Django中以比应用更高的粒度对单元测试进行分组?

4 投票
2 回答
1959 浏览
提问于 2025-04-16 20:28

在一个Django项目中,单元测试通常是按应用程序来组织的,Django提供了一个功能,可以运行所有测试、单个应用的测试、单个测试案例或单个测试方法。

不过,我发现一个应用中的测试案例通常属于不同的逻辑组或集群,有时候只运行某一组测试会非常有用。比如说:

  • 我有几个测试案例,分别覆盖一个模型的不同配置,我想在开发这个模型时只运行这些测试(这特别麻烦,因为简单的方法是把这些测试案例放在一起,这样你就有了一个可以轻松运行的单一测试案例,但读起来和维护起来都非常困难)。
  • 我有一系列工具类,它们的测试非常快,因为不涉及数据库。在重构这些工具类时,我不需要运行模型测试和视图测试。

我搜索了一下。虽然把测试分成多个文件相对简单(可以参考这两个问题),但似乎没有简单的方法可以单独运行测试组。

所以,我是不是漏掉了什么?有什么秘诀可以把测试分组吗?

2 个回答

2

对于Django版本低于1.6
我个人的做法是:

你需要一个init文件:

myapp/tests/__init__.py :

from test1 import *
from test2 import *

def suite():
    import unittest
    #import doctest # If you want to use doctest

    TEST_CASES = ( 
     'sendim.tests.test1',
     'sendim.tests.test2',
    )   
    suite = unittest.TestSuite()

    #suite.addTest(doctest.DocTestSuite(object)) # object which have doctest
    for t in TEST_CASES :
        suite.addTest(unittest.TestLoader().loadTestsFromModule(__import__(t, globals(), locals(), fromlist=["*"])))
    return suite

然后,比如说你有一个名为'TestCase1'的测试案例文件:

myapp/tests/test1.py :

from django.utils import unittest

class TestCase1(unittest.TestCase) :
    # Your testcase

如果你运行 ./manage.py test myapp,它会执行所有的测试案例。
如果你运行 ./manage.py test myapp.TestCase1,它只会执行这个特定的测试案例。

2

可以看看Python的nose测试框架,它提供了一种解决这个问题的方法。

具体来说,你可以给测试加标签或者设置一些属性。这样的话,你就可以只运行那些带有特定标签的测试,可能是在一个应用里,或者在整个项目中。

https://nose.readthedocs.org/en/latest/plugins/attrib.html?highlight=tags

需要注意的是,nose是对unittest的扩展,所以你现有的Django unittest测试套件很可能已经可以用nose来运行了。

撰写回答