Python 单元测试框架入门

-- xyb [DateTime(2004-09-22T01:51:30Z)] TableOfContents

Python 单元测试框架入门

作者:Xie Yanbo,版权:创作共用/cc 1.0

Python 中的单元测试框架也叫做 [http://pyunit.sourceforge.net/ PyUnit],在源代码中是一个叫做 unittest 的模块,它提供了对单元测试的支持。

拿一个例子来看一下:

   1 from unittest import TestCase
   2 
   3 class simpleTest(TestCase):
   4     def setUp(self):
   5         pass
   6 
   7     def tearDown(self):
   8         pass
   9 
  10     def testExample(self):
  11         self.assertEqual(len('abc'), 3)
  12 
  13     def testOther(self):
  14         self.assertNotEqual('abc', 'ABC')
  15         self.assertNotEqual(0, 1)
  16 
  17 if __name__ == '__main__':
  18     import unittest
  19     unittest.main()

如果要编写一个测试程序,需要以 unittest.TestCase 为基类派生,这样 unittest 就可以自动找到这些测试类了。这样的一个测试类中,凡是以“test”开头的方法,都是一个测试用例。比如上面的例子中就有两个,testExample 和 testOther。unittest 会自动统计测试用例的个数,并在最后的测试报告中指出测试成功了几个,有那些失败。TestCase 还有两个很有用的方法:在每个测试用例执行之前,写在 setUp 中的代码都会被执行,用来初始化测试环境;而 tearDown 中的代码则负责清除每个测试用例遗留的垃圾,恢复现场。这两个方法可以一起使用,也可以分别使用,或者象例子中的一样,完全不用。例子中最后的一段代码可以让这个测试文件做为一个单独的程序来运行。

其实对于每个测试用例来说,不外乎三个过程:准备,执行目标,测试结果。比如我们可以把上面 testExample 的一行代码拆开,就可以看的更清楚了:

   1     def testExample(self):
   2         astr = 'abc'                  # 这个测试用例的准备工作
   3         length = len(astr)           # 执行要测试的目标函数、方法
   4         self.assertEqual(length, 3)   # 测试,看看和预期结果是否相符

这样的测试程序文件,经常以 testSomeModule.py 或 test_somemodule.py 的名字命名,一般保存在被测试模块的一个子目录 tests 中。

大多数模块都会提供一个一次执行所有测试用例的程序文件,这个文件常以 runalltests.py 或 alltests.py 命名,保存在模块的根目录中。下面是它的一个例子文件:

   1 import unittest
   2 import sys
   3 
   4 sys.path.append('./')
   5 sys.path.append('../')
   6 sys.path.append('./tests')
   7 
   8 modules_to_test = (
   9 'test_somemoudle',
  10 'test_another',
  11 'test_foo',
  12 )
  13 
  14 def suite():
  15     alltests = unittest.TestSuite()
  16     for module in map(__import__, modules_to_test):
  17         alltests.addTest(unittest.findTestCases(module))
  18     return alltests
  19 
  20 if __name__ == '__main__':
  21     unittest.main(defaultTest='suite')

程序的开头把当前目录、上一级目录和子目录 tests 都放入系统搜寻路径中。这是为了 Python 程序 import 模块代码和测试代码时更容易找到它们。紧接着,在 modules_sto_test 列表中定义了所有要执行的测试程序。也有一些开发者喜欢让程序自动寻找 test 开头的 .py 文件,这视开发者的习惯而不同;自动寻找的代码也并不复杂。suite 方法根据前面定义的列表把所有测试用例都找出来。最后通过调用 unittest 的 testrunner 就可以启动我们的所有测试了,我们只要稍等一会儿,它就会把最终的测试报告放到我们面前 :)