python基础教程总结14——测试
1. 先测试,后编码
对程序的各个部分建立测试也是非常重要的(这也称为单元测试)。测试驱动编程:Test-driven programming
1)精确的需求说明:
程序设计的理念是以编写测试程序开始,然后编写可通过测试的程序。测试程序就是你的需求说明,它帮助你在开发程序时不偏离需求
举例:编写一个模块,其中包括一个使用给定的宽和高计算长方形面积的函数。在开始编码前,首先要编写一个单元测试,其中包括带有几个答案已经清楚的例子:
from area import rect_area height = 3
width =4
correct_answer = 12
answer = rect_area(height, width)
if answer == correct_answer:
print 'Test passed'
else:
print 'Test failed'
2)为改变而计划:
自动化测试除了在编写程序上给予巨大帮助外,还可以避免在实施修改时增加错误
代码覆盖度——coverage是测试知识中重要的部分。在运行测试的时候,有可能并没有运行代码的全部,即使在理想情况下也是这样(理想的情况应该是运行程序的所有可能状态,使用所有可能的输入,但是这不太可能)。优秀的测试程序组的目标之一是拥有良好的覆盖度,实现这个目标的方法之一是使用覆盖度工具,它可以衡量在测试过程中实际运行的代码的百分比。目前还没有可用的标准化覆盖度工具,搜索“Python测试覆盖度”会找到一个些可用的工具。其中一个是trace.py程序
3)测试的4步:
A:指出需要的新特性。可以先记录下来,然后为其编写一个测试
B:编写特性的概要代码,这样程序就可以运行而没有任何语法等方面的错误,但是测试会失败。看到测试失败是很重要的,这样就能确定测试可以失败。如果测试代码中出现 了错误,那么就有可能不管出现任何情况,测试都会成功,这样等于没测试任何东西。再强调一遍:在试图让测试成功前,先要看到它失败
C:为特性的概要编写虚设代码(dummy code),能满足测试要求就行。不用准确地实现功能,只要保证测试可以通过即可。这样一来就可以保证在开发的时候总是通过测试了 (除了第一次运行测试的时候),甚至在最初实现功能时亦是如此
D:现在重写(或者重构,Refactor)代码,这样它就会做自己应该做的事,从而保证测试一直重构
2. 测试工具
标准库中的模块可以帮助我们自动完成测试过程:
unitest:通用测试框架
doctest:简单一些的模块,是检查文档用的,但是对于编写单元测试也很在行
1) doctest:交互式解释器的会话可以是将文档字符串(docstring)写入文档的一种有用的形式。假如,假设我编写了一个求数字的平方的函数,并且在它的文档字符串中添加了一个例子:
def square(x):
'''
Squares a number and returns the result. >>> square(2)
4
>>> square(3)
9
'''
return x*x
文档字符串中也包括了一些文本。这和测试又有什么关系?假设square函数定义在my_math模块(也就是叫做my_math.py的文件)中。之后就可以在底部增加下面的代码:
def square(x):
'''
Squares a number and returns the result. >>> square(2)
4
>>> square(3)
9
'''
return x*x if __name__ == '__main__':
import doctest.my_math
doctest.testmod(my_math)
doctest.testmod函数从一个模块读取所有文档字符串,找出所有看起来像是在交互式解释器中输入的例子的文本,之后检查例子是否符合实例要求(如果想实践“先测试,后编码”的编程方式,unittest框架是更好的选择)
为了获得更多输入,可以为脚本设定-v(意为verbose,即详述)选项开关:$ python my_math.py -v
2)unittest:doctest简单易用,unittest(基于Java的流行测试框架JUnit)则更灵活和强大。
假设要写模块my_math,其中包括计算乘积的函数product。从哪开始呢?对于测试来说,当然(位于文件test_my_math.py中)是使用unittest模块中的TestCase类
#使用unittest框架的简单测试
import unittest, my_math class ProductTestCase(unittest.TestCase): def testIntegers(self):
for x in range(-10,10):
for y in range(-10,10):
p = my_math.product(x,y)
self.failUnless(p == x*y, 'Tnteger multiplication failed') def testFloats(self):
for x in range(-10,10):
for y in range(-10,10):
x = x/10.0
y = y/10.0
p = my_math.product(x,y)
self.failUnless(p == x*y, 'Float multiplication failed') #unittest.main函数负责运行测试,它会实例化所有TestCase的子类,运行所有名字以test开头的方法
if __name__ == '__main__' : unitteset.main()
如果定义了叫做startUp和tearDown的方法,它们就会在运行每个测试方法之前和之后执行,这样就可以用这些方法为所有测试提供一般的初始化和清理代码,这被称为测试夹具(test fixture)
3:单元测试以外的东西:
源代码检查和分析:源代码检查是一种寻找代码中普通错误或者问题的方法(有点像编译器处理静态语言,但远不如此)。分析则是查明程序到底跑多快的方法。之所以按照这个顺序讨论这章的主题,是因为黄金法则“使其工作、使其更好、使其更快”的缘故。单元测试可以让程序可以工作,源代码检查可以让程序更好,最后,分析会让程序更快。
1)使用PyChecker和PyLint检查源代码
2)分析:试图让代码提速前,有个非常重要的规则需要注意(以及KISS原则,Keep It Small and Simple,即让它小且简单,或者YAGNI原则,You Ain't Gonna Need It,即并不需要它)——不成熟的优化是万恶之源
拿Unix的发明人之一Ken Thompson的话说就是“拿不准的时候,就穷举”。换句话说,如果不是特别需要的话,就不要在精巧的算法或者漂亮的优化技巧上有过多的担心。如果程序已经够快了,那么干净、简单并且易懂的代码的价值比稍微快一点的程序要高得多。
如果必须进行优化的话,那么绝对应该再做其他事情之前对其进行分析(profile)。这是因为很难估计到瓶颈在哪里,除非你的程序非常简单。标准库中已经包含了一个叫做profile的分析模块(还有个更快的嵌入式C语言版本,叫hotshot)。使用分析程序非常简单,是要使用字符串参数调用它的run方法就行了
>>> import profile
>>> from my_math import product
>>> profile.run('product(1,2)')
这样做会打印出信息,其中包括各个函数和方法调用的次数,以及每个函数所花费的时间。如果提供了文件名,比如'my_math.profile'作为第二个参数来运行,那么结果就会保存到文件中。可在之后使用pastats模块检查分析结果:
>>> import pstats
>>> p = pstats.Stats('my_math.profile')
标准库中还包含一个名为timeit的模块,它是测试python小代码段运行时间的简单方法
python基础教程总结14——测试的更多相关文章
- Python基础教程(第2版 修订版) pdf
Python基础教程(第2版 修订版) 目录 D11章快速改造:基础知识11.1安装Python11.1.1Windows11.1.2Linux和UNIX31.1.3苹果机(Macintosh)41. ...
- Python基础教程(第3版)PDF高清完整版免费下载|百度云盘
百度云盘:Python基础教程(第3版)PDF高清完整版免费下载 提取码:gkiy 内容简介 本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基础知识和基 ...
- Python基础教程2上的一处打印缺陷导致的代码不完整#1
#1对代码的完善的 出现打印代码处缺陷截图: 图片上可以看到,定义的request根本没有定义它就有了.这个是未定义的,会报错的,这本书印刷问题,这个就是个坑,我也是才发现.花了点时间脱坑. 现在发完 ...
- python基础教程1:入门基础知识
写在系列前,一点感悟 没有梳理总结的知识毫无价值,只有系统地认真梳理了才能形成自己的知识框架,否则总是陷入断片儿似的学习-遗忘循环中. 学习方法真的比刻苦"傻学"重要多了,而最重要 ...
- Python基础教程学习笔记:第一章 基础知识
Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...
- Python 基础教程之包和类的用法
Python 基础教程之包和类的用法 建立一个文件夹filePackage 在filePackage 文件夹内创建 __init__.py 有了 __init__.py ,filePackage才算是 ...
- 学习参考《Python基础教程(第3版)》中文PDF+英文PDF+源代码
python基础教程ed3: 基础知识 列表和元组 字符串 字典 流程控制 抽象(参数 作用域 递归) 异常 魔术方法/特性/迭代器 模块/标准库 文件 GUI DB 网络编程 测试 扩展python ...
- python基础教程(2)
Python 基础教程 Python 是一种解释型.面向对象.动态数据类型的高级程序设计语言. 执行Python程序 对于大多数程序语言,第一个入门编程代码便是 "Hello World!& ...
- Python基础教程 (第2+3 版)打包pdf|内附网盘链接提取码
<Python基础教程 第3版>包括Python程序设计的方方面面:首先,从Python的安装开始,随后介绍了Python的基础知识和基本概念,包括列表.元组.字符 ...
随机推荐
- 【Java面试题系列】:Java基础知识常见面试题汇总 第二篇
文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 1.JDK,JRE,JVM三者之间的联系和区别 你是否考虑过我们写的x ...
- include跟include_once 以及跟require的区别
include如果引入两个文件,都有一个相同的函数名,那么就会发生重定义的错误.使用include_once可以避免此错误,一般都_once用的比较多.应该根据实际情况需求include和_once的 ...
- 用MATLAB进行数据分析
- 洛谷P1298 最接近的分数
P1298 最接近的分数 题目描述 给出一个正小数,找出分子(非负)不超过M,分母不超过N(正数)的最简分数或整数,使其最接近给出的小数.“最接近”是指在数轴上该分数距离给出的小数最近,如果这个分数不 ...
- Openjudge2729 Blah数集(单调队列)
2729:Blah数集 总时间限制: 3000ms 内存限制: 65536kB 描述 大数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下:(1) a是集合Ba ...
- 约数和问题 (codevs2606 && 洛谷2424)
P2424 约数和 题目背景 Smart最近沉迷于对约数的研究中. 题目描述 对于一个数X,函数f(X)表示X所有约数的和.例如:f(6)=1+2+3+6=12.对于一个X,Smart可以很快的算出f ...
- Solidity 最新 0.5.8 中文文档发布
本文首发于深入浅出区块链社区 热烈祝贺 Solidity 最新 0.5.8 中文文档发布, 这不单是一份 Solidity 速查手册,更是一份深入以太坊智能合约开发宝典. 翻译说明 Solidity ...
- String,StringBuffer和StringBuilder
String,StringBuffer和StringBuilder分别应该在什么情况下使用? String 是Java的字符串类,其实质上也是用Char类型存储的,但是除了hash属性,其他的属性都声 ...
- null is not an object (evaluating 'Picker._init')
安装完react-native-picker后,init出现报错,其实是原生配置还没完全生效,重启项目就可以了
- Visiual Studio CLR20r3问题
原文转自:http://blog.sina.com.cn/s/blog_3f2ef11801013p8c.html(刘帝勇的大观园) 看到有更新,习惯性的点了,升级到Visiual Studio Ul ...