Python day 9(7) 测试

一:单元测试

单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。

比如对函数abs(),我们可以编写出以下几个测试用例:

  1. 输入正数,比如11.20.99,期待返回值与输入相同;

  2. 输入负数,比如-1-1.2-0.99,期待返回值与输入相反;

  3. 输入0,期待返回0

  4. 输入非数值类型,比如None[]{},期待抛出TypeError

把上面的测试用例放到一个测试模块里,就是一个完整的单元测试。

如果单元测试通过,说明我们测试的这个函数能够正常工作。如果单元测试不通过,要么函数有bug,要么测试条件输入不正确,总之,需要修复使单元测试能够通过。

我们来编写一个Dict类,这个类的行为和dict一致,但是可以通过属性来访问,用起来就像下面这样:

1 >>> d = Dict(a=1, b=2)
2 >>> d['a']
3 1
4 >>> d.a
5 1

mydict.py代码如下:

 1 class Dict(dict):
 2 
 3     def __init__(self, **kw):
 4         super().__init__(**kw)
 5 
 6     def __getattr__(self, key):
 7         try:
 8             return self[key]
 9         except KeyError:
10             raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
11 
12     def __setattr__(self, key, value):
13         self[key] = value

为了编写单元测试,我们需要引入Python自带的unittest模块,编写mydict_test.py如下

 1 import unittest
 2 
 3 from mydict import Dict
 4 
 5 class TestDict(unittest.TestCase):
 6 
 7     def test_init(self):
 8         d = Dict(a=1, b='test')
 9         self.assertEqual(d.a, 1)
10         self.assertEqual(d.b, 'test')
11         self.assertTrue(isinstance(d, dict))
12 
13     def test_key(self):
14         d = Dict()
15         d['key'] = 'value'
16         self.assertEqual(d.key, 'value')
17 
18     def test_attr(self):
19         d = Dict()
20         d.key = 'value'
21         self.assertTrue('key' in d)
22         self.assertEqual(d['key'], 'value')
23 
24     def test_keyerror(self):
25         d = Dict()
26         with self.assertRaises(KeyError):
27             value = d['empty']
28 
29     def test_attrerror(self):
30         d = Dict()
31         with self.assertRaises(AttributeError):
32             value = d.empty

编写单元测试时,我们需要编写一个测试类,从unittest.TestCase继承

test开头的方法就是测试方法,不以test开头的方法不被认为是测试方法,测试的时候不会被执行。

编写单元测试时,我们需要编写一个测试类,从unittest.TestCase继承。

test开头的方法就是测试方法,不以test开头的方法不被认为是测试方法,测试的时候不会被执行。

对每一类测试都需要编写一个test_xxx()方法。由于unittest.TestCase提供了很多内置的条件判断,我们只需要调用这些方法就可以断言输出是否是我们所期望的。最常用的断言就是assertEqual()

1 self.assertEqual(abs(-1), 1) # 断言函数返回的结果与1相等

另一种重要的断言就是期待抛出指定类型的Error,比如通过d['empty']访问不存在的key时,断言会抛出KeyError

1 with self.assertRaises(KeyError):
2     value = d['empty']

 

而通过d.empty访问不存在的key时,我们期待抛出AttributeError

1 with self.assertRaises(AttributeError):
2     value = d.empty

二:运行单元测试

法一:

最简单的运行方式是在mydict_test.py的最后加上两行代码:

1 if __name__ == '__main__':
2     unittest.main()

 

这样就可以把mydict_test.py当做正常的python脚本运行:

1 $ python mydict_test.py

 

 法二:(推荐此法)

在命令行通过参数-m unittest直接运行单元测试

1 $ python -m unittest mydict_test
2 .....
3 ----------------------------------------------------------------------
4 Ran 5 tests in 0.000s
5 
6 OK

 

 三:setUp与tearDown

可以在单元测试中编写两个特殊的setUp()tearDown()方法。这两个方法会分别在每调用一个测试方法的前后分别被执行。

setUp()tearDown()方法有什么用呢?设想你的测试需要启动一个数据库,这时,就可以在setUp()方法中连接数据库,在tearDown()方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码:

1 class TestDict(unittest.TestCase):
2 
3     def setUp(self):
4         print('setUp...')
5 
6     def tearDown(self):
7         print('tearDown...')

 

四:文档测试 (Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试。)

 1 # mydict2.py
 2 class Dict(dict):
 3     '''
 4     Simple dict but also support access as x.y style.
 5 
 6     >>> d1 = Dict()
 7     >>> d1['x'] = 100
 8     >>> d1.x
 9     100
10     >>> d1.y = 200
11     >>> d1['y']
12     200
13     >>> d2 = Dict(a=1, b=2, c='3')
14     >>> d2.c
15     '3'
16     >>> d2['empty']
17     Traceback (most recent call last):
18         ...
19     KeyError: 'empty'
20     >>> d2.empty
21     Traceback (most recent call last):
22         ...
23     AttributeError: 'Dict' object has no attribute 'empty'
24     '''
25     def __init__(self, **kw):
26         super(Dict, self).__init__(**kw)
27 
28     def __getattr__(self, key):
29         try:
30             return self[key]
31         except KeyError:
32             raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
33 
34     def __setattr__(self, key, value):
35         self[key] = value
36 
37 if __name__=='__main__':
38     import doctest
39     doctest.testmod()

 

运行python mydict2.py

1 $ python mydict2.py

什么输出也没有。这说明我们编写的doctest运行都是正确的。

 

posted @ 2018-01-11 20:23  灰灰辉  阅读(166)  评论(0编辑  收藏  举报