码迷,mamicode.com
首页 > 编程语言 > 详细

Python自动单元测试框架(摘要笔记)

时间:2015-11-21 00:24:37      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

规范Python单元测试

原文:https://www.ibm.com/developerworks/cn/linux/l-pyunit/

测试是一个贯穿于整个开发过程的连续过程,从某个意义上说,软件开发的过程实际上就是测试过程。正如Martin Fowler所说的"在你不知道如何测试代码之前,就不该编写程序。而一旦你完成了程序,测试代码也应该完成。除非测试成功,你不能认为你编写出了可以工作的程序。"

测试最基本的原理就是比较预期结果是否与实际执行结果相同,如果相同则测试成功,否则测试失败。为了更好地理解PyUnit这一自动测试框架的作用,先来看一个简单的例子,假设我们要对例1中的Widget类进行测试:

# 例1. widget.py
# 将要被测试的类
class Widget:
    def __init__(self, size = (40, 40)):
        self._size = size
    def getSize(self):
        return self._size
    def resize(self, width, height):
        if width  0  or height < 0:
            raise ValueError, "illegal size"
        self._size = (width, height)
    def dispose(self):
        pass

采用手工方式进行单元测试的Python程序员很可能会写出类似例2的测试代码来,

# 例2. manual.py
from widget import Widget
# 执行测试的类
class TestWidget:
    def testSize(self):
        expectedSize = (40, 40);
        widget = Widget()
        if widget.getSize() == expectedSize:
            print "test [Widget]: getSize works perfected!"
        else:
            print "test [Widget]: getSize doesn‘t work!"
# 测试
if __name__ == __main__:
    myTest = TestWidget()
    myTest.testSize()

稍一留心你不难发现这种手工测试方法存在许多问题。首先,测试程序的写法没有一定的规范可以遵循,十个程序员完全可能写出十种不同的测试程序来,如果每个Python程序员都有自己不同的设计测试类的方法,光维护被测试的类就够麻烦了,谁还顾得上维护测试类。其次,需要编写大量的辅助代码才能进行单元测试,例1中用于测试的代码甚至比被测试的代码还要多,而这毫无疑问将增大Python程序员的工作量。

为了让单元测试代码能够被测试和维护人员更容易地理解,最好的解决办法是让开发人员遵循一定的规范来编写用于测试的代码,具体到Python程序员来讲,则是要采用PyUnit这一自动测试框架来构造单元测试用例。目前PyUnit已经得到了大多数Python开发人员的认可,成了事实上的单元测试标准。如果采用PyUnit来进行同样的测试,则测试代码将如例3所示:

# 例3. auto.py
from widget import Widget
import unittest
# 执行测试的类
class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget()
    def tearDown(self):
        self.widget = None
    def testSize(self):
        self.assertEqual(self.widget.getSize(), (40, 40))
# 构造测试集
def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase("testSize"))
    return suite
# 测试
if __name__ == "__main__":
    unittest.main(defaultTest = suite)

在采用PyUnit这一单元测试框架后,用于测试的代码做了相应的改动:

  • 用import语句引入unittest模块。
  • 让所有执行测试的类都继承于TestCase类,可以将TestCase看成是对特定类进行测试的方法的集合。
  • 在setUp()方法中进行测试前的初始化工作,并在tearDown()方法中执行测试后的清除工作,setUp()和tearDown()都是TestCase类中定义的方法。
  • 在testSize()中调用assertEqual()方法,对Widget类中getSize()方法的返回值和预期值进行比较,确保两者是相等的,assertEqual()也是TestCase类中定义的方法。
  • 提供名为suite()的全局方法,PyUnit在执行测试的过程调用suit()方法来确定有多少个测试用例需要被执行,可以将TestSuite看成是包含所有测试用例的一个容器。

虽然看起来有点复杂,但PyUnit使得所有的Python程序员都可以使用同样的单元测试方法,测试过程不再是杂乱无章的了,而是在同一规范指导下进行的有序行为,这就是使用PyUnit这一自动单元测试框架所带来的最大好处。

-----------------------------------------------------------------------------------

              废话介绍完了

-----------------------------------------------------------------------------------

自动测试框架PyUnit

PyUnit模块中定义了一个名为main的全局方法,使用它可以很方便地将一个单元测试模块变成可以直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中的测试方法,并自动执行它们。如果Python程序员能够按照约定(以test开头)来命名所有的测试方法,那就只需要在测试模块的最后加入如下几行代码即可:

    if __name__ == "__main__":
    unittest.main()

使用TestRunner来实施测试的例子如例7所示,

# 例7. text_runner.py
from widget import Widget
import unittest
# 执行测试的类
class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget()
    def tearDown(self):
        self.widget.dispose()
        self.widget = None
    def testSize(self):
        self.assertEqual(self.widget.getSize(), (40, 40))
    def testResize(self):
        self.widget.resize(100, 100)        
        self.assertEqual(self.widget.getSize(), (100, 100))        
# 测试
if __name__ == "__main__":
    # 构造测试集
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase("testSize"))
    suite.addTest(WidgetTestCase("testResize"))
    
    # 执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

PyUnit模块中定义了一个名为main的全局方法,使用它可以很方便地将一个单元测试模块变成可以直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中的测试方法,并自动执行它们。如果Python程序员能够按照约定(以test开头)来命名所有的测试方法,那就只需要在测试模块的最后加入如下几行代码即可:

    if __name__ == "__main__":
    unittest.main()

测试类WidgetTestCase中的所有测试方法都将被自动执行,但如果只想执行testSize()方法,可以使用如下命令:

python main_runner.py WidgetTestCase.testSize

为了使单元测试更具亲合力,PyUnit软件包中还提供了一个图形界面测试脚本unittestgui.py,将其复制到当前目录后,可以执行下面的命令来启动该测试工具,对main_runner.py脚本中的所有测试用例进行测试:

python unittestgui.py main_runner

小结

测试是保证软件质量的关键,新的软件开发方法要求程序员在编写代码前先编写测试用例,并在软件开发过程中不断地进行单元测试,从而最大限度地减少缺陷(Bug)的产生。软件单元测试是XP方法的基石,测试框架为程序员进行单元测试提供了统一的规范,Python程序员可以使用PyUnit作为软件开发过程中的自动单元测试框架。

Python自动单元测试框架(摘要笔记)

标签:

原文地址:http://www.cnblogs.com/addf/p/4982645.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!