单元测试与技术探究
作为面向对象设计的一部分,通常会创建一个类似本节代码中所演示的技术探究模块,我们会把它分为3个部分。首先,是以下这个全局的抽象类。
import types
import unittest
class TestAccess( unittest.TestCase ):
def test_should_add_and_get_attribute( self ):
self.object.new_attribute= True
self.assertTrue( self.object.new_attribute )
def test_should_fail_on_missing( self ):
self.assertRaises( AttributeError, lambda: self.object.
undefined )
抽象类TestCase的子类中定义了一些希望类可以通过的测试。实际被测试的对象被忽略了。它通过self.object被引用,但是没有提供定义,使得TestCase子类保持抽象。每个具体类都会需要setUp()方法。
以下是3个具体的TestAccess子类,会包含以下3种不同对象的测试。
class SomeClass:
pass
class Test_EmptyClass( TestAccess ):
def setUp( self ):
self.object= SomeClass()
class Test_Namespace( TestAccess ):
def setUp( self ):
self.object= types.SimpleNamespace()
class Test_Object( TestAccess ):
def setUp( self ):
self.object= object()
TestAccess类的每个子类都提供了所需要的setUp()方法。每个方法创建了一种不同的被测试对象。第1个是空类的实例。第2个是types.SimpleNamespace的实例。第3个是object的实例。
为了运行这些测试,需要创建一个组件,来阻止我们运行TestAccess抽象类的测试。
以下是探究的其余部分。
def suite():
s= unittest.TestSuite()
s.addTests( unittest.defaultTestLoader.loadTestsFromTestCase(Test
EmptyClass) )
s.addTests( unittest.defaultTestLoader.loadTestsFromTestCase(Test
Namespace) )
s.addTests( unittest.defaultTestLoader.loadTestsFromTestCase(Test
Object) )
return s
if name == "_main":
t= unittest.TextTestRunner()
t.run( suite() )
现在我们得到了具体的证据,object类的使用方式与其他类是不同的。进一步说,我们有了一个可以用于演示其他可行(或不可行)设计的测试。例如,用于演示types. SimpleNamespace作为空类行为的测试。
我们跳过了很多单元测试用例的细节,会在第15章“可测试性的设计”中进行详细介绍。
