先学习下如何调试Python程序,然后再学习下如何做单元测试。Python的pdb模块同GDB非常相似,不过它只是GDB一个小小的子集,似乎不支持调试多线程程序。在网上找到一篇不错的文章:用PDB库调试Python程序。写了个小例子,练习下使用pdb调试和做单元测试吧。
下面是一个简单的数学库,实现了简单的加减函数。代码如下:
主程序会调用数学库中的函数,代码如下:
08 | c = math_utils.add(a, b); |
下面演示了几条最基本的调试命令的使用方法,包括”list”,”continue”,”break”,”run”,”backtrace”等等。打断点的时候不要打在函数的def处。如果这样做,import的时候会运行到这个位置,真正调用函数时却不会停住。impor的时候会生成Python内部的运行指令,因此会运行到每个函数定义的地方。
01 | henshao@henshao-desktop:~/source$ python -m pdb main.py |
02 | > /home/henshao/source/main.py(3)() |
06 | Documented commands (type help ): |
07 | ======================================== |
08 | EOF bt cont enable jump pp run unt |
09 | a c continue exit l q s until |
10 | alias cl d h list quit step up |
11 | args clear debug help n r tbreak w |
12 | b commands disable ignore next restart u whatis |
13 | break condition down j p return unalias where |
15 | Miscellaneous help topics: |
16 | ========================== |
23 | (Pdb) b math_utils.py:4 |
24 | Breakpoint 1 at /home/henshao/source/math_utils.py:4 |
27 | Continue execution, only stop when a breakpoint is encountered. |
29 | Restarting main.py with arguments: |
31 | > /home/henshao/source/main.py(3)() |
34 | > /home/henshao/source/math_utils.py(4)add() |
37 | /usr/lib/python2.6/bdb.py(368)run() |
38 | -> exec cmd in globals, locals |
40 | /home/henshao/source/main.py(8)() |
41 | -> c = math_utils.add(a, b); |
42 | > /home/henshao/source/math_utils.py(4)add() |
Python的单元测试框架同JUnit差不多,因为它们的开发者都是Kent Beck,接口都是一样的。使用setUp和tearDown做准备和收尾工作。每个要测试的接口都以”test”开始。在math_utils.py添加下面这段代码便可。
03 | class MathTestCase(unittest.TestCase): |
11 | self.assertEqual(add(4, 5), 9) |
14 | self.assertEqual(sub(8, 5), 3); |
17 | suite = unittest.TestSuite() |
18 | suite.addTest(MathTestCase()) |
21 | if __name__ == "__main__": |
直接运行程序,得到以下输出:
1 | henshao@henshao-desktop:~/source$ python math_utils.py |
3 | ---------------------------------------------------------------------- |
上面这种方式将测试代码同源代码混杂在一起,并不是一种很好的方式。可以将测试用例的代码放到一个单独的unittest目录中。对每个用例设计一个test case,然后使用下面这种方式添加测试用例。
1 | if __name__ == "__main__": |
2 | suite = unittest.TestSuite() |
4 | suite.addTest(MathTestCase("testAdd")) |
5 | suite.addTest(MathTestCase("testSub")) |
7 | runner = unittest.TextTestRunner() |
如果安装python-tk包,就可以使用图形界面来跑测试用例了。PyUnit源码包中有一个unittestgui.py文件,将该文件拷贝到测试用例代码目录下。输入如下命令,注意math_utils不要加”.py”后缀,否则会出错。
1 | ./unittestgui.py math_utils |
测试界面如下:
阅读(2467) | 评论(0) | 转发(0) |