Python脚本覆盖率分析方法介绍

简介:

背景
Python凭借其面向对象的特点,清晰简洁的语法以及丰富而强大的类库,已经在越来越多的应用领域中获得了青睐。
测试工作中涉及的Python脚本也越来越多,这就产生了通过统计的覆盖率来衡量测试效果的需求,
二进制程序可以使用BullseyeCoverage进行覆盖率分析,Python脚本是否也有比较好的工具来进行覆盖率分析呢,这里介绍一个针对python脚本的覆盖率分析工具。 
Coverage3.3.1基本功能介绍
Coverage是一个用于统计python代码覆盖率的工具,支持HTML报告生成,最新版本支持对分支覆盖率进行统计。
获取地址:http://pypi.python.org/pypi/coverage
官方站点:http://nedbatchelder.com/code/coverage/


安装
Coverage支持Python2.5/2.6/3.1,和其他python第三方module安装方式相同, 获获取后python setup.py install即可。

运行
Coverage支持两种运行方式:一种是命令行的方式,另一种方式是通过在脚本中调用Coverage的API来控制覆盖率的统计,下面一一介绍。

(1)命令行方式
这种方式比较简单,只需要指定被测脚本,不用对被测代码进行任何修改。
安装好Coverage后,会在python/bin/生成一个coverage脚本,通过调用coverage run <被测脚本>进行覆盖率分析。
Example:
coverage run test.py foo bar
这样就完成了一次覆盖率分析,其中run是coverage的参数,test.py是被测脚本,foo、bar是test.py的调用参数。


(2)API方式
除了命令行方式,coverage提供了更灵活的API调用方式来进行覆盖率分析。
API方式需要在被测代码前后嵌入,举一个最简单的例子:

 

from coverage import coverage

cov = coverage() #生成coverage对象
cov.start() #开始分析
function_to_be_tested() #待测函数
cov.stop() #分析结束
cov.save() #将覆盖率结果保存到数据文件

 

这样就通过在代码中调用API完成了对目标函数的覆盖率分析。
这种统计方式的好处在于可以灵活的控制覆盖率分析start和stop的代码段,可以满足不同的需求。


查看覆盖率结果
通过(2)中介绍的方法完成覆盖率分析后,就可以查看覆盖率分析的结果了。Coverage提供了几种覆盖率结果的展现方式: 
(1)简单文本方式
使用命令行coverage report,或者在代码中调用coverage对象的report方法
可以获取简单文本格式的覆盖率结果:

 

Name是被分析Module的名称,
Stmts/Exec表示语句总数/执行到的语句数
Branch/BrExec表示分支数/执行到的分支数,Cover表示覆盖率
Cover=(Exec+BrExec)/(Stmts+Branch) 
(2)HTML格式
使用命令行coverage html,或者在代码中调用coverage对象的html_report方法,可以获取html格式的覆盖率分析报告,并且提供对源码详细覆盖情况的标注报告,报告范例可以在http://nedbatchelder.com/code/coverage/sample_html/查看。 
(3)XML格式
类似的,通过coverage xml或者调用coverage.xml_report来生成。 
进阶功能
Coverage还提供了很多有用的特性/功能,这里介绍几个比较有用的。 
(1)数据文件合并combine
默认情况下,覆盖率数据会被写入到当前目录的.coverage文件中,但在有些情况下需要产生多个.coverage文件
(比如多进程并发执行自动化测试,使用coverage –p产生形如.coverage.hostname.pid的多个数据文件),最后进行合并分析总的覆盖率,这时候就可以使用combine功能,合并成一个.coverage文件。 
(2)分支覆盖分析branch
分支覆盖是在最新版本的Coverage中提供的。
API模式下,只需在创建coverage对象时制定branch=True即可,cov = coverage.coverage(branch = True);
命令行模式只能通过修改.coveragerc来打开分支覆盖功能。 
(3)排除特定代码exclude
代码中可能有一部分代码是出于debug用途的,或者处在不会被触及的分支,在这种情况下,在统计覆盖率的时候可能不希望这些代码被统计在内,可以通过Coverage提供的exclude功能在统计的时候排除这些代码。
简单的排除方法是在需要被排除的代码行或者分支后面添加注释,内容为”#pragma no cover”,这样被注释的分支和代码行就会在统计中被排除。
另外可以使用正则表达式来匹配需要排除的代码行,通过coverage.exclude(regex)或者在.coveragerc中添加exclude_lines来指定。 
(4).coveragerc
如上所述,一部分功能在命令行模式下只能通过修改.coveragerc来打开,如branch覆盖,exclude正则表达式等等:


# .coveragerc to control coverage.py
[run]
branch = True

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover

# Don't complain about missing debug-only code:
def __repr__
if self\.debug

经验分享
对于单元测试和直接退出的脚本,以上介绍的方式能很好的工作,但是对于后台服务类,程序中有一个mainLoop的python脚本,情况会有些许不同。
假设我们有一个脚本程序:


#mock_server.py

import time
a = 0
while True:
a += 1
if a>30:
a = 0
time.sleep(1)

我们用coverage run mock_server.py &>log &启动,一段时间后kill该进程,再用coverage report查看,会发现覆盖率结果是空的。
百思不得其解下只好查看coverage源代码,原来,coverage在实现上使用了atexit模块注册一个回调函数,在python退出时将内存中的覆盖率结果写到文件中,所以被测脚本只有正常退出或者以SIGINT 2信号退出,才能得到覆盖率结果,如果直接kill(SIGTERM 15)或者用其他信号终止进程,覆盖率结果将会丢失。
所以,要解决覆盖率丢失的问题,一种方法是在测试完毕后使用kill -2来结束进程,使atexit能捕捉到退出的信号;
或者,可以使用coverage的API方式,安装一个自定义的signal handler,捕捉其他信号,在程序退出的时候做一次coverage.save()。

 (作者:linyi) 
















本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/743425,如需转载请自行联系原作者

相关文章
|
1天前
|
存储 Linux Shell
python移除/删除非空文件夹/目录的最有效方法是什么?
python移除/删除非空文件夹/目录的最有效方法是什么?
7 0
|
1天前
|
缓存 人工智能 算法
编写高效的Python脚本:性能优化的策略与技巧
编写高效的Python脚本需要综合考虑多个方面,包括代码结构、数据结构和算法选择等。本文将探讨在Python编程中提高脚本性能的方法,包括优化数据结构、选择合适的算法、使用Python内置函数以及通过并行和异步编程提升效率。这些技巧旨在帮助开发者在不同应用场景中编写出高性能的Python代码。
|
2天前
|
语音技术 开发者 Python
python之pyAudioAnalysis:音频特征提取分析文档示例详解
python之pyAudioAnalysis:音频特征提取分析文档示例详解
8 0
|
2天前
|
数据可视化 大数据 Python
python大数据分析处理
python大数据分析处理
7 0
|
2天前
|
机器学习/深度学习 人工智能 大数据
AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀
AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀
|
4天前
|
Python
【Python 基础】Python中的实例方法、静态方法和类方法有什么区别?
【5月更文挑战第6天】【Python 基础】Python中的实例方法、静态方法和类方法有什么区别?
|
4天前
|
机器学习/深度学习 自然语言处理 算法
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
|
4天前
|
Python Perl
Python中的字符串分析:判断字符串中是否包含字母
Python中的字符串分析:判断字符串中是否包含字母
9 0
|
4天前
|
机器学习/深度学习 数据可视化 决策智能
Python中使用Gradient Boosting Decision Trees (GBDT)进行特征重要性分析
Python中使用Gradient Boosting Decision Trees (GBDT)进行特征重要性分析
14 0
|
4天前
|
数据处理 Python
Python中每个字段增加多条数据的高效方法
Python中每个字段增加多条数据的高效方法
10 1