应用python的unit测试工具PyUnit

来源:互联网 发布:练武术的软件 编辑:程序博客网 时间:2024/06/07 21:51

为了保证python代码的质量,实施unit测试必不可少。而python本身做unit测试就很容易,但是如果在项目中实施,就会遇到一些问题:

1.测试函数的形式不同一

2.测试代码的可维护性会因为不同的人的不同编写习惯而变得难于维护

3.比较难以引入外部工具进行统一运行和结果整合

4.测试用例的质量存在风险


从如上几点可以发现,PyUnit的一个主要作用其实是提供了一套已经测试过的,质量有一定保障的的统一接口。虽然项目的实际情况会有所不懂,但是一个好的思想就是“以测试驱动开发”,笔者简单的理解,就是:"先想怎么测试,再想怎么实现。"


如果我们要测试一个python模块,笔者一般会在编写这个模块的时候,就在模块文件的最下方,加上:

if __name__ == '__main__':
在这行之下,编写测试用的函数,用来验证自己实现的函数。这样一边调试,一边写。

当写好后,新建一个测试的文件,直接将测试用的函数拷贝到这里,稍作调整,就作为unit测试文件了。


以下关于PyUnit的介绍都可以在http://www.oschina.net/question/12_27127#TESTDOCS中找到,这里本人只是做一个简单的摘要,便于使用时参考:

PyUnit的module名是 unittest,同样你也需要引入你要测试的模块,这里是一个举一个例子假设我们要测试名为readxlsx的模块

'''PyUnit module''' import unittest  '''Test Object''' import readxlsx

先写测试用例

#------------------------------------------------------------------------------- # Test Case #------------------------------------------------------------------------------- class ReadxlsxTestCase(unittest.TestCase):     def setUp(self):         self.input = '%s %s' % ('a'*10, 'a'*10)          def tearDown(self):        pass          def testBreakString(self):         '''We'll test the string breaking funtion'''         ret = readxlsx.BreakString(self.input, 10)         out = ['aaaaaaaaaa aaaaaaaaa', 'a']         if ret != out:             self.fail("BreakString failed!")          def testSplit(self):         """Check that string can be split correctly"""         ret = False         self.failIf(ret)          def testRead(self):         """Check that file can be read correctly"""         ret = True         self.failUnless(ret) # fail
这里简单说一下几个点:

1.setUp()和 tearDown()函数分别负责Test Case的创建和销毁操作,不同的testXXX()函数是Test Case的测试部分。

2.使用 fail(), failIf, failUnless() 这些函数是因为用python的assert方法可能会在成为字节码的情况下被优化掉,我选择多使用TestCase类中所特有的判断方法。

3.使用doc string的作用是为了在错误的时候能够输入这条doc的内容,这样你就会从测试结果中看到失败的case的内容了。


将case组合成test suite:

#------------------------------------------------------------------------------- # Test Suite #-------------------------------------------------------------------------------         class MyTestSuite(unittest.TestSuite):    def __init__(self):        unittest.TestSuite.__init__(self,map(ReadxlsxTestCase,                                    ("testSplit",                                     "testRead",                                     "testBreakString")))

在Test Suite中,case的执行顺序会按照你在如上代码中编写的顺序执行。