Python代码覆盖率工具coverage.py其实是一个第三方的包,同时支持Python2和Python3版本。
安装也非常简单,直接运行:
pip install coverage
安装完成后,会在Python环境下的\Scripts下看到coverage.exe;
首先我们编写一个简易计算器的程序:
# mymath.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(numerator, denominator):
return float(numerator) / denominator
接着来编写基于unittest的单元测试用例:
# test_mymath.py
import mymath
import unittest
class TestAdd(unittest.TestCase):
"""
Test the add function from the mymath library
"""
def test_add_integers(self):
"""
Test that the addition of two integers returns the correct total
"""
result = mymath.add(1, 2)
self.assertEqual(result, 3)
def test_add_floats(self):
"""
Test that the addition of two floats returns the correct result
"""
result = mymath.add(10.5, 2)
self.assertEqual(result, 12.5)
def test_add_strings(self):
"""
Test the addition of two strings returns the two string as one
concatenated string
"""
result = mymath.add('abc', 'def')
self.assertEqual(result, 'abcdef')
if __name__ == '__main__':
unittest.main()
下面打开CMD命令窗口并进入代码文件所在目录。
1. 使用coverage run命令运行测试用例
coverage run test_mymath.py
运行一个.py的文件方式:python test.py
现在使用coverage执行.py的文件方式:coverage run test.py
会自动生成一个覆盖率统计结果文件(data file):.coverage,这个文件在你的test.py的文件对应目录下。
2. 生成覆盖率报告
有了覆盖率统计结果文件,只需要再运行report参数,就可以在命令里看到统计的结果。
coverage report -m
-m参数表示显示有哪些行没有被覆盖。
可以看到计算器程序mymath.py的测试覆盖率是62%,其中13,17,21行未运行。
3. 生成HTML报告
生成html的测试报告。
coverage html
运行后在代码文件所在目录生成了htmlcov文件夹,打开index.html查看报告
点击报告中的mymath.py,可以打开该文件的覆盖详情,会飘红展示哪些代码未被运行。
因为我们的单元测试代码只是测试了mymath.add(),所以其他函数里的代码未被覆盖,这时就需要我们补充测试用例了。
输出结果意义
Stmts 总的有效代码行数(不包含空行和注释行)
Miss 未执行的代码行数(不包含空行和注释行)
Branch 总分支数
BrMiss 未执行的分支数
Cover 代码覆盖率
Missing 未执行的代码部分在源文件中行号
命令详解
coverage run --help # 打印帮助信息
coverage run test_xxx.py # 执行test_xxx.py文件,会自动生成一个覆盖率统计结果文件.coverage
coverage report -m(带有详细信息) # 查看coverage报告,读取.coverage文件并打印到屏幕上,可以在命令行里看到统计结果
coverage html -d report # 生成显示整体的covergae html形式的报告 (在当前同路径下生成一个report文件夹,里面包含html形式的报告。通过查看report文件夹下的内容即可)
4. 其他功能
除了使用命令行,还可以在python代码中直接调用coverage模块执行代码覆盖率的统计。使用方法也非常简单:
import coverage
cov = coverage.coverage()
cov.start()
# .. run your code ..
cov.stop()
cov.save()