技术开发 频道

详解Python 3.1的新变化之标准程序库篇

  七、单元测试的改进

  Python语言具有一个标准的unittest模块,可以用来编写xUnit风格的测试。您可以重复利用设置/拆卸代码,以适当的方式来组织你的测试,甚至可以运行你的测试。下面是一个用于部分函数add5()的单元测试。TestAdd5类由unittest.TestCase派生而来,并定义了一个setUp()方法,该方法将在执行每个测试方法之前调用。它能确保某些一致状态可以用于所有的测试方法。此测试方法会调用unittest的assertEqual()和assert_()方法。如果任何调用失败,托管的测试方法就会认为出现了一个故障,并转到下一个测试。

import unittest
from functools import partial
def add(a, b):
  
return a + b
add5
= partial(add, 5)
class TestAdd5(unittest.TestCase):
  
def setUp(self):
    self.values
= range(1, 10)
  
def test_positive(self):
    
for v in self.values:
      self.assertEquals(add5(v), v
+ 5)
  
def test_negative(self):
    
for v in self.values:
      self.assertEquals(add5(
-v), 5 - v)
  
def test_zero(self):
    self.assert_(add5(0)
== 5)
if __name__ == '__main__':
    unittest.main()

  在这个例子中,当此模块运行的时候unittest.main()也会运行,并找到所有的测试类(在本例中只有一个),然后运行它们的测试方法并报告运行结果:

  ...

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

  Ran 3 tests in 0.000s

  OK

  Python 3.1能够进行空白测试,并将其标记为“expected to fail.”。空白测试在许多情况下都非常有用。举例来说,有时候为了节约时间而只想运行目前处理的测试,或者在一种平台上运行时想跳过其他平台有关的测试。当在test-first模式下工作的时候,预期的故障是非常有用的。在这个例子中,用于新的功能的测试预期失败,知道修复了代码或者实现了新功能为止。下面是add5的改进版本,它可以操作带有数字的字符串。新版本中添加了一个test_string方法,它从序列中取出所有的值,并将其转化为字符串,然后再将其传递给add5函数:

  def test_string(self):

  
for v in self.values:

  self.assertEquals(add5(str(v)), v
+ 5)

  运行此测试,选择将会产生一个和预期的一样的错误:

  > python3.1 unittest_test.py

  ..E.

  
=============================================

  ERROR: test_string (
__main__.TestAdd5)

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

  Traceback (most recent call last):

  File
"unittest_test.py", line 26, in test_string

  self.assertEquals(add5(str(v)), v
+ 5)

  File
"unittest_test.py", line 4, in add

  
return a + b

  TypeError: unsupported operand type(s)
for +: 'int' and 'str'

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

  Ran
4 tests in 0.001s

  现在,让我们跳过零测试,并允许test_string方法失败:

  @unittest.skip("skipping this guy")

  
def test_zero(self):

  self.assert_(add5(0)
== 5)

  @unittest.expectedFailure()

  
def test_string(self):

  
for v in self.values:

  self.assertEquals(add5(str(v)), v
+ 5)

  现在,此测试成功运行,并报告跳过和预期的故障,如下所示:

  > python3.1 unittest_test.py

  ..xs

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

  Ran
4 tests in 0.001s

  OK (skipped
=1, expected failures=1)

  Unittest模块的另一个新特性是可以使用assertRaises作为上下文管理器:

  with self.assertRaises(ImportError):

  
import no_such_module

  在Python 3.0和早先的版本中,您必须在另一函数中包装此代码,并将其传递给assertRaises,如下所示:

  def import_no_such_module():

  
import no_such_module

  self.assertRaises(ImportError, import_no_such_module)

  另外,还增加了许多assertXXX()函数,具体情况请参考有关文档。

  八、小结

  Python 3.0发布七个月之后,Python核心开发人员于2009年6月27日发布了新的Python 3.1版本。虽然此3.1版本只是对Python 3.0的一次小型升级,但是它不仅为开发者带来许多让人感兴趣的特性,同时在性能方面也有所改善。本文中,我们为读者详细介绍了Python 3.1版本在标准程序库方面的变化,在下一篇中我们将要为读者介绍新版本在性能方面的改进。

0
相关文章