coverage.py的覆盖率统计原理
来源:互联网 发布:r软件干预模型 编辑:程序博客网 时间:2024/05/17 02:34
原文出处:http://blog.theerrorlog.com/how-coverage-py-produce-coverage-statistics.html
在Erlang下,用rebar可以在运行单元测试的同时调用cover模块,从而得 到单元测试的覆盖率,这是很方便的一个功能。最近发现Python下的nose也可 以通过--with-coverage
选项达到类似的效果,而这个选项实际上是调用了 coverage.py. 出于好奇,我研究了一下coverage.py的工作原理。
coverage.py的使用方法
抄一下coverage.py主页的例子:
用
coverage
命令运行你的程序$ coverage run my_program.py arg1 arg2 blah blah ..your program's output.. blah blah
生成报告
1234567
$ coverage report -mName Stmts Miss Cover Missing-------------------------------------------------------my_program 20 4 80% 33-35, 39my_other_module 56 6 89% 17-23-------------------------------------------------------TOTAL 76 10 87%
或者,生成更漂亮的HTML报告
$ coverage html
好吧对于一个开发工具来说,coverage
算是挺成功的,因为够傻瓜。和 nosetests
搭配使用的时候甚至更简单,加一个参数就可以了,“猴子都能学 会”……
既然这里有个脚本入口coverage
,我们就从这里开始吧~
工作原理
首先从源码库把代码clone下来,观察一下setup.py
:
12345
scripts = [ 'coverage = coverage:main', 'coverage%d = coverage:main' % sys.version_info[:1], 'coverage-%d.%d = coverage:main' % sys.version_info[:2], ]
这里说明,coverage
命令其实是调用了coverage
模块下的main
函数,根据这个 函数的内容——为了简洁起见这里省略掉一堆处理命令行参数的代码——我们可以跟踪到 coverage/control.py
文件中的Coverage
类。
这个类包含了所有从数据采集到生成报告的代码,我们只关心它如何采集到程序执行 数据就好了。而“采集数据”这个操作,通过这里的源码可以推断出,是由 coverage/collector.py
中的Collector
类和PyTracer
类,又或者是CTracer
类合作完成的。
PyTracer
和CTracer
其实在逻辑上是等价的,只不过一个是纯Python实现,而另 一个是C语言实现。为什么会这样呢?我们先继续看下去……
既然这两个类是一样的,我们还是来看稍微漂亮一点的Python版本吧。PyTracer
的start
函数有句docstring说,这个函数是用来“Return a Python function suitable for use with sys.settrace()”的。
好吧,真相大白了,coverage.py利用了Python虚拟机的trace机制。我怎么就没想 到呢?
sys.settrace(...)
这个函数的文档在这里,所以参数和用法说明什么的我就省略了。实际上 这是Python程序调试机制的核心——几乎每种虚拟机或者操作系统,都有类似的 机制,用于干预其上执行的程序,可以认为这是给对应的调试器开的“后门”。 例如Erlang下有erlang:trace(...),POSIX系统下也有ptrace; Erlang的dbg模块正是基于erlang:trace(...)的,而gdb也是在ptrace基 础上工作的。
大家都知道调试器都是牛逼到可以把运行中的程序拆开再装回去的,它们依赖 的trace机制自然也是大杀器。但是这货通常要启动各种钩子(Hook),会严 重拖慢被trace的程序的运行速度,所以一般不会用在生产环境中。
这也就解释了为什么coverage.py里会有两个tracer:tracer代码基本上在 Python虚拟机的每步执行中都要被调用一遍,所以有一个C语言实现是能有效 提高效率的。那为什么还需要Python实现?这是为了支持CPython以外的虚拟 机,像PyPy、Jython之类。
其他利用trace机制的有趣玩意
pycallgraph能生成Python程序中的函数调用关系图(Call Graph)。
另外我在很~久之前用ptrace做了一个更改cd
命令行为的小玩具 :)(转载注:作者写的)
- coverage.py的覆盖率统计原理
- Python 代码覆盖率统计工具 coverage.py
- Python 代码覆盖率统计工具 coverage.py
- django工程黑盒测试使用coverage.py进行覆盖率统计
- 使用coverage统计python web项目的代码覆盖率
- 利用coverage统计Python代码覆盖率
- 使用coverage工具统计python单元测试覆盖率
- 使用coverage工具统计python单元测试覆盖率
- google工具的Coverage代码覆盖率详解
- coverage 测试代码覆盖率
- 使用Coverage分析Python web项目的代码覆盖率
- Pydev 的覆盖率测试python coverage以及其他使用
- 多模块的覆盖率统计
- python coverage代码覆盖率工具
- Cobertura统计Equinox的bundles的覆盖率
- 使用EclEmma统计代码的测试覆盖率
- JUnit测试:让代码覆盖率(Code Coverage)报表显示每个方法的覆盖情况
- gcov lcov进行 android apk项目的 code coverage 代码覆盖率检测
- 将字符串中的html转义字符转换为字符
- 图形学中的贴图采样、走样与反走样等
- 关于内存警告
- Android Toast 设置到屏幕中间以及其他自定义Toast的实现方法
- Linux内核调试方法总结
- coverage.py的覆盖率统计原理
- c++ primer学习笔记 第 10 章 关联容器
- MySQL设置编码和项目中如何统一编码
- 解决PHP服务端返回json字符串有特殊字符的问题
- maven教程一之入门
- 二叉树,完全二叉树,满二叉树,二叉排序树
- SQL2005,如何将数据库从一台电脑上转到另一台电脑上?
- hadoop生态系统
- jQuery end()的使用