# 单元测试 ```python # mydict.py class Dict(dict): def __init__(self, **kw): super(Dict, self).__init__(**kw) def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(r"Dict object has no attribute '%s'."%key) def __setattr__(self, key, value): self[key] = value ``` 编写单元测试时,我们需要编写一个测试类,从`unittest.TestCase`继承。以`test`开头的方法就是测试方法,不以`test`开头的方法不被认为是测试方法,测试的时候不会被执行。 ```python # 单元测试文件mydict_test.py import unittest from mydict import Dict class TestDict(unittest.TestCase): def test_init(self): d = Dict(a=1, b='test') self.assertEqual(d.a, 1) self.assertEqual(d.b, 'test') self.assertTrue(isinstance(d, dict)) def test_key(self): d = Dict() d['key'] = 'value' self.assertEqual(d.key, 'value') def test_attr(self): d = Dict() d.key = 'value' self.assertTrue('key' in d) self.assertEqual(d['key'], 'value') def test_keyerror(self): d = Dict() with self.assertRaises(KeyError): value = d['empty'] def test_attrerror(self): d = Dict() with self.assertRaises(AttributeError): value = d.empty if __name__ == '__main__': unittest.main() ``` 对每一类测试都需要编写一个`test_xxx()`方法。由于`unittest.TestCase`提供了很多内置的条件判断,我们只需要调用这些方法就可以断言输出是否是我们所期望的。最常用的断言就是`assertEqual()`。 ## 运行单元测试 ```bash # 单一运行 python mydict_test.py # 多个测试文件一起运行 python -m unittest mydict_test ``` ## setUp与tearDown 可以在单元测试中编写两个特殊的`setUp()`和`tearDown()`方法。这两个方法会分别在每调用一个测试方法的前后分别被执行。设想你的测试需要启动一个数据库,这时,就可以在`setUp()`方法中连接数据库,在`tearDown()`方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码。 ```python class TestDict(unittest.TestCase): def setUp(self): print("setUp...") def tearDown(self): print("tearDown...") ``` 可以再次运行测试看看每个测试方法调用前后是否会打印出`setUp...`和`tearDown...`可以再次运行测试看看每个测试方法调用前后是否会打印出`setUp...`和`tearDown...`。