Python 测试(16) 持续更新
编写测试代码的有用工具。
如 标准库的测试和分析工具(profiling),代码分析器PyChecker和Pylint。
更多有关 编程实践、编程思想的内容。
测试驱动编程
1、精确的需求说明
开发软件某部分时,必须首先知道软件要解决什么问题,它要达到什么目的。需要通过编写一份需求说明明确程序的目标。需求说明是描述程序必须满足的需求的文档。
需求的种类还包括客户满意度那类模糊的概念。
测试驱动编程的核心理念是从编写测试程序开始,然后编写可以通过测试的程序。
举个例子
from area import rect_area height = 3 width = 4 correct_value = 12 answer = rect_area(height, width) if answer == correct_value: print 'Test passed' else: print 'Test failed'
area.py
def rect_area(height, width): return height * width
2、代码覆盖率(代码覆盖度)
代码覆盖 ( 英语: Code coverage )是软体测试中的一种度量 ,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率 。
代码覆盖是由系统化软体测试所衍生的方式。
详细查看 https://zh.wikipedia.org/zh/%E4%BB%A3%E7%A2%BC%E8%A6%86%E8%93%8B%E7%8E%87
Python中,可以通过搜索 Python测试覆盖度 关键字搜索找到一些可用工具。
有些时候,你可能会因为要广泛地测试一切代码而感到不知所措。不用担心,程序用不着测试上百种输入和状态变量的组合,至少开始的时候不用。测试驱动编程最重要的部分时通过在编码时实际地重复运行方法(或者函数、脚本)吗,获取所做事情的连续反馈。如果想要代码正确度(以及覆盖度)方面增加信心,那么可以增加更多的测试。
3、测试3个步骤
1、指出需要的功能,记录下来,为其写一个测试。
2、编写准确地实现功能代码,保证测试可以通过。
3、重构代码,是它完成准确的功能,保证测试一直成功。
在完成编码时,应保证代码出于健康状态,不遗留任何失败的测试。
4、测试工具
doctest、unitest。
doctest
它是直接从文档字符串(docstring)写入文档的一种形式,测试代码,如
def square(x): ''' :param x: 2 :return: 4 >>> square(4) 16 >>> square(16) 256 ''' return x ** x if __name__ == '__main__': import doctest, my_path doctest.testmod(my_path)
运行
D:\python_basic_course\course_16\doc_test>python my_path.py -v Trying: square(4) Expecting: 16 ********************************************************************** File "D:\python_basic_course\course_16\doc_test\my_path.py", line 6, in my_path. square Failed example: square(4) Expected: 16 Got: 256 Trying: square(16) Expecting: 256 ********************************************************************** File "D:\python_basic_course\course_16\doc_test\my_path.py", line 8, in my_path. square Failed example: square(16) Expected: 256 Got: 18446744073709551616L 1 items had no tests: my_path ********************************************************************** 1 items had failures: 2 of 2 in my_path.square 2 tests in 2 items. 0 passed and 2 failed. ***Test Failed*** 2 failures.
错误被捕捉盗了,得到了有关哪里出错的,并有详细的解释。
上面把 x ** x 改成 x * x 就会得到正确的结果。
unittest
unittest是基于Java流行测试框架JUnit,所以灵活、强大。
简单的示例
import unittest, my_path class ProductTestCase(unittest.TestCase): def testIntegers(self): for x in xrange(-10, 10): for y in xrange(-10, 10): p = my_path.product(x, y) self.failUnless(p == x * y, 'Integer mutiplication failed') def testFloats(self): for x in xrange(-10, 10): for y in xrange(-10, 10): x = x / 10.0 y = y / 10.0 p = my_path.product(x, y) self.failUnless(p == x * y, 'Float mutiplication failed') if __name__ == '__main__': unittest.main()
my_path.py
def product(x, y): return x ** y
运行
D:\python_basic_course\course_16\unittest>python test_my_math.py FF ====================================================================== FAIL: testFloats (__main__.ProductTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_my_math.py", line 17, in testFloats self.failUnless(p == x * y, 'Float mutiplication failed') AssertionError: Float mutiplication failed ====================================================================== FAIL: testIntegers (__main__.ProductTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_my_math.py", line 9, in testIntegers self.failUnless(p == x * y, 'Integer mutiplication failed') AssertionError: Integer mutiplication failed ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=2)
关于更多TestCase方法,可以查看官方手册。
也有针对unittest的GUI,可以查看PyUnit(unittest的另外一个名字) 。
4、单元测试以外的内容
测试是至关重要的,除了测试以外,还需要源代码检查和性能分析。源代码检查一种寻找代码中普通错误或者问题的方法。性能分析则是查明程序到底能跑多快的方法。使用遵循“使其工作、使其更好、使其更快”的黄金法则,
使用Pychecker和PyLint检查源代码
Pycheck 检查Python源代码、寻找提供的参数不满足函数要求等错误唯一工具。
tabnanny 检查缩进格式
PyLint 只有大多数PyCheck拥有的特性,以及其他功能(如变量名名称是否符合命名规范、是否遵循自己的编码标准)
安装工具,可以通过包管理系统 如 Debian APT 和 Gentoo Portage 安装。然后使用标准命令安装
python setup.py install
PyLint还需要 Logilab Common 库。
在Window可以把工具 Pychecker.bat 和 pylint.bat 批处理文件 作为命令行工具使用。添加PATH环境变量中。使能其在命令行中运行。
如 检查文件
pychecker file1.py file2.py ...
Pylint使用介绍
https://www.ibm.com/developerworks/cn/linux/l-cn-pylint/
性能分析
在试图让代码提速前,需要遵循规则
KISS = Keep It Samll and Simple(让它小且简单)
YAGNI = You Ain't Gonna Need It (并不需要它)
关于软件规则,可以看
http://blog.csdn.net/zj_show/article/details/8078447
还有其他的名言
不成熟的优化是万恶之源。
拿不准的时候,就穷举。
性能分析库
profile 分析模块、更快的嵌入式C语言版本 hotshot 模块。
import profile from my_path import product profile.run('product(1, 2)')
关于更多的,可以参考
http://chenxiaoyu.org/2013/08/28/python-profile.html
如果担心程序速度,可以增加一个分析程序并且强制进行约束(如果程序用了多于1秒来完成工作就十失败)的单元测试。但不推荐这样做。着谜于分析,会让你的注意力不知不觉从真正重要的事情离开了--------比如干净、易懂的代码。

浙公网安备 33010602011771号