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秒来完成工作就十失败)的单元测试。但不推荐这样做。着谜于分析,会让你的注意力不知不觉从真正重要的事情离开了--------比如干净、易懂的代码。

 

posted @ 2016-08-04 09:27  笨重的石头  阅读(254)  评论(0)    收藏  举报