Saturday, October 2, 2010

unittest

这是一个完整的 unit test 工具。doctest 的优势是可以在不改变原始 module 文件的同时加入 unit test 的信息,但是对于一些占用了 __name__ == '__main__' 的 python 程序而言,直接使用 unittest 是更加合适的选择。unittest 可以作为单独的测试文件存在,我们可以将 testcase 通过类(继承 unittest.TestCase)封装成为不同的部分,然后对某些功能写成该类的 test_* 方法,最后使用 assert* 方法进行判定,另外,我们还可以重载 setUp 方法,用于初始化这个 testcase。我们可以在 __name__ == '__main__' 时调用 unittest.main() 执行所有的 test case。另外文档中还介绍了更加细致的用法。下面是一个简单的 unittest 例子:
#!/usr/bin/env python

import unittest

class ListMethodTest( unittest.TestCase ):
    def setUp( self ):
        self.a = range( 10 )
        self.b = [ 1, 1, 1 ]
        self.c = [ 0, 0, 0 ]
        self.d = [ 1, 0, 1 ]

    def test_All( self ):
        self.assertEqual( all(self.a), False )
        self.assertEqual( all(self.b), True )
        self.assertEqual( all(self.c), False )

    def test_Any( self ):
        self.assertTrue( any(self.a) )
        self.assertTrue( any(self.b) )
        self.assertTrue( any(self.d) )

if __name__ == '__main__':
    unittest.main()
运行结果如下:
$ ./test05.py 
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
$ ./test05.py -v
test_All (__main__.ListMethodTest) ... ok
test_Any (__main__.ListMethodTest) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
我们可以看看 TestCase 还有一些什么方法:
  • tearDown 提供了和 setUp 相反的作用,用于清理 TestCase 失败后的问题;
  • @unittest.skip 可以标注一些不使用的 test case;类似的有 unittest.skipIf 和 unittest.skipUnless。
  • 如果确定应该出现错误可以用 @unittest.expectedFailure;
  • 与 setUp 和 tearDown 对应的还有 setUpClass 和 tearDownClass;
  • 类似于 assertEqual 之类的还可以 assert 大小 In、re 等等,或者 assertRaise 表示应该抛出何种异常。
  • 可以用类似的 fail* 系列表示测试失败;
  • 可以用 TestSuite 将一堆 TestCase 放在一起;
  • 可以用 unittest 的 discover 模块进行某个目录下所有 test case 的自动执行;

No comments:

Post a Comment