代码写多了越发觉得测试的重要性,之前一直喜欢“目测”的做法已经不值得推荐了。当然,这只是一个玩笑。
在Python代码里测试大概有这么几种:doctest、unittest和nose(第三方工具)。
个人推荐nose,简单的话doctest也已经足够了。
首先:
- 代码要易于测试,代码写完对应的测试应该配套跟上。
- 测试要简单,轻便。
先说最简单的doctest吧,顾名思义,doctest就是在文档(docstring)里完成测试。看以下例子(/tmp/1.py):
def add(a, b): """ >>> add(10, 20) 30 """ return a + b if __name__ == '__main__': import doctest doctest.testmod()
可以看出doctest是不是很简单?是不是想起了普通解释器(>>>),运行一下测试(注意-v选项):
smallfish@debian:~$ python /tmp/1.py -v Trying: add(10, 20) Expecting: 30 ok 1 items had no tests: __main__ 1 items passed all tests: 1 tests in __main__.add 1 tests in 2 items. 1 passed and 0 failed. Test passed.
作为简单的模块或者工具,main里实现测试已经足够了。但是稍大一些工程或应用,doctest太多的话,看上去会觉得有点臃肿。
下面介绍下nose,偷偷的说下,nose是支持doctest、unittest测试的,所以嘛。先安装一下:
smallfish@debian:~$ pip install nose
继续跑一下上面的例子:
smallfish@debian:~$ nosetests /tmp/1.py --with-doctest -v Doctest: 1.add ... ok ---------------------------------------------------------------------- Ran 1 test in 0.006s OK
好吧,写点常见的例子,目录结构如下(foo模块以及foo的测试代码):
smallfish@debian:~$ tree /tmp/foomodule/ /tmp/foomodule/ |-- foo | |-- a.py | |-- b.py | `-- __init__.py `-- tests |-- test_a.py `-- test_b.py
模块代码如下:
# /tmp/foomodule/foo/a.py def add(a, b): return a + b def double(a): return a * 2 # /tmp/foomodule/foo/b.py import memcache class Cache: def __init__(self, server): self.cache = memcache.Client([server]) def get(self, name): return self.cache.get(name) def set(self, name, value): return self.cache.set(name, value) def delete(self, name): return self.cache.delete(name) def close(self): self.cache.disconnect_all()
对应的测试代码:
# /tmp/foomodule/tests/test_a.py from foo.a import add, double def test_add(): v = add(10, 20) assert v == 30 def test_double(): v = double(10) assert v == 20 # /tmp/foomodule/tests/test_b.py from foo.b import Cache class TestCache: def setUp(self): self.cache = Cache("127.0.0.1:11211") self.key = "name" self.value = "smallfish" def tearDown(self): self.cache.close() def test_00_get(self): v = self.cache.get(self.key) assert v == None def test_01_set(self): v = self.cache.set(self.key, self.value) assert v == True v = self.cache.get(self.key) assert v == self.value def test_02_delete(self): v = self.cache.delete(self.key) assert v == True
先不解释,跑一跑(-v -s选项,针对当前路径下tests目录测试):
smallfish@debian:/tmp/foomodule$ nosetests -s -v test_a.test_add ... ok test_a.test_double ... ok test_b.TestCache.test_00_get ... ok test_b.TestCache.test_01_set ... ok test_b.TestCache.test_02_delete ... ok ---------------------------------------------------------------------- Ran 5 tests in 0.024s OK
简单吧?nose默认是当前目录下tests目录进行测试,默认规则:文件(含有test),函数(test_开头),类(Test开头)。
nose完整文档请参考:http://nose.readthedocs.org/en/latest/
转载请注明:爱开源 » Python Testing