测试 Django 程序(二)

Posted in Python on 十二月 17th, 2007 by admin – Be the first to comment

编写单元测试

象文档测试一样,Django 单元测试使用标准库的一个模块:unittest。这个模块使用一种不同的途径定义测试,一种基于类的途径。

也象文档测试那样,对特定的 Django 程序,测试运行器在两个地方寻找单元测试:

  • models.py 文件。测试运行器寻找该模块中所有 unittest.TestCase 的子类。
  • 程序目录中的 tests.py 文件。例如,models.py 所在的目录。测试运行器同样搜寻该模块中所有 unittest.TestCase 的子类。

下面例子中的 unittest.TestCase 子类相当于上文例子中给出的文档测试:

1
2
3
4
5
6
7
8
9
10
11
import unittest
from myapp.models import Animal
 
class AnimalTestCase(unittest.TestCase):
    def setUp(self):
        self.lion = Animal.objects.create(name="lion", sound="roar")
        self.cat = Animal.objects.create(name="cat", sound="meow")
 
    def testSpeaking(self):
        self.assertEquals(self.lion.speak(), 'The lion says "roar"')
        self.assertEquals(self.cat.speak(), 'The cat says "meow"')

运行测试时,测试工具默认会搜寻 models.py 和 tests.py 中的所有测试设定(也就是,unittest.TestCase 的子类),针对这些测试设定自动构建一套测试程序,并且运行它。

在 Django 的开发版本中,还有另外一种方式来为某个模块定义测试程序组:如果你在 models.py 或 tests.py 中定义了名叫 suite() 的函数,Django 的测试运行器将使用该函数来构造该模块的测试程序组。这遵从单元测试的建议组织形式。更多关于如何构造复杂测试程序组的信息,请参考 Python 文档。

更多关于 unittest 的细节,参考标准库 unittest 文档

我应该使用哪个?

由于 Django 同时支持这两种标准的 Python 测试框架,使用哪一种方式完全取决于你以及你自己的口味。你甚至可以两种都用。

尽管如此,对于初接触测试的开发者来说,如何作出选择看起来似乎仍旧很迷茫。这里,因此,列出一些二者之间的关键区别,可以帮助你选择哪种方式更适合你:

  • 如果你使用 Python 不久,doctest 感觉可能会更 “pythonic” 一些。它的设计初衷就是使测试编写尽可能的简单,所以它不需要你编写额外的类或方法。你只需要简单的将测试放在文档字符串就行了。这也可以为文档的编写和审校带来额外的好处。
    如果你刚刚开始编写测试,使用文档测试也许可以上手的更快些。
  • unittest 框架对来自 Java 的开发者来说感觉或许会很亲切。unittest 借鉴了 Java 的 JUnit,所以如果你使用过 JUnit 或者类似的测试框架,你会觉得很舒服。

  • 如果你需要写一批带码相近的测试,那么你应当重新估量 unittest 基于类和方法的框架体系。它使得抽象通用任务成为通用方法变得很容易。该框架同时还支持显示的安装和卸载程序,这给了你很高的可控制性,在你的测试程序所运行的环境中。

重申,记住你可以同时使用这两种系统(甚至在同一程序中)。最后,多数项目最终都会同时使用它们。不同环境中使用它们各自的优点。

运行测试

一旦编写完测试代码,你就可以使用你项目的 manage.py 工具来运行它们:

1
$ ./manage.py test

默认情况下,这会运行所有在 INSTALLED_APPS 中的应用程序。如果你只想对个别的程序运行测试,在命令后加上该程序的名字就行了。例如,如果你的 INSTALLED_APPS 包含 ‘myproject.polls’ 和 ‘myproject.animals’,你可以使用如下的命令单独运行 myproject.animals 的单元测试:

1
# ./manage.py test animals

请注意,这里我们使用的是 animals,而不是 myproject.animals。

Django 开发版本中的更新:如果你使用单元测试,在选择执行哪些测试时,你可以更加明确的指定。要运行某个程序特定情形的一个测试(例如,“编写单元测试”一节中定义的 AnimalTestCase ),在命令行上加上该测试情形的标记:

1
$ ./manage.py test animals.AnimalTestCase

甚至更加具体,要运行某个测试情行的个别方法,加上该方法的标记:

1
$ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
Pages: Prev 1 2 3 ...6 7 8 9 10 ...52 53 54 Next