python覆盖率测试_Python单元测试:unit test code coverage

开发环境配置

单元测试覆盖率

unittest: Python built-in standard library

Pytest: a third party Python testing framework

Coverage.py:one of the most popular code coverage tools for Python

Pytest-cov:Python plugin to generate coverage reports. In addition to functionalities supported by coverage command, it also supports centralized and distributed testing

Nose可以将所有的单元测试文件一次全部执行,并且提供了coverage的插件,能够统计整体的覆盖率,官网有详细的使用介绍https://pypi.org/project/nose/

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp$ pwd

/c/Users/bobho/Desktop/tmp

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp$ dir

app.py test.py

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp$ cat app.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

def process_input(a, b, operation):

if operation == "add":

return a + b

if operation == "subtract":

return a - b

if operation == "multiple":

return a * b

if operation == "divide":

if b == 0:

return "Invalid input"

return a / b

if __name__ == "__main__":

print(process_input(int(sys.argv[1]), int(sys.argv[2]), sys.argv[3]))

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ cat app.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

def process_input(a, b, operation):

if operation == "add":

return a + b

if operation == "subtract":

return a - b

if operation == "multiple":

return a * b

if operation == "divide":

if b == 0:

return "Invalid input"

return a / b

if __name__ == "__main__":

print(process_input(int(sys.argv[1]), int(sys.argv[2]), sys.argv[3]))

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ python test.py

test_0010_add (__main__.TestApp) ... ok

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ pip3 install coverage

Collecting coverage

Downloading https://files.pythonhosted.org/packages/9c/c2/036ccdc0bbcef7d980dd f89c132b39c81b2ba645f1c904b0c8edc957f60a/coverage-4.5.2-cp36-cp36m-win_amd64.whl (183kB)

Installing collected packages: coverage

Successfully installed coverage-4.5.2

You are using pip version 9.0.3, however version 18.1 is available.

You should consider upgrading via the 'python -m pip install --upgrade pip' comm and.

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ coverage run test.py

test_0010_add (__main__.TestApp) ... ok

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ coverage report

Name Stmts Miss Cover

-----------------------------

app.py 14 9 36%

test.py 15 0 100%

-----------------------------

TOTAL 29 9 69%

添加单元测试,更新后的test.py如下

import unittest

from app import process_input

class TestApp(unittest.TestCase):

def setUp(self):

self.a = 10

self.b = 5

def test_0010_add(self):

result = process_input(self.a, self.b, "add")

self.assertEqual(result, 15)

def test_0020_subtract(self):

result = process_input(self.a, self.b, "subtract")

self.assertEqual(result, 5)

def suite():

suite = unittest.TestSuite()

suite.addTests(

unittest.TestLoader().loadTestsFromTestCase(TestApp)

)

return suite

if __name__ == "__main__":

unittest.TextTestRunner(verbosity=2).run(suite())

再次运行覆盖率检查,可以看到覆盖率已经提升

$ coverage run test.py

test_0010_add (__main__.TestApp) ... ok

test_0020_subtract (__main__.TestApp) ... ok

----------------------------------------------------------------------

Ran 2 tests in 0.000s

OK

bobho@LAPTOP-ET2KSKHR MINGW64 ~/Desktop/tmp

$ coverage report

Name Stmts Miss Cover

-----------------------------

app.py 14 7 50%

test.py 18 0 100%

-----------------------------

TOTAL 32 7 78%

运行coverage html会在当前目录下面生成一个htmlcov,打开其中的app_py.html可以看到具体哪些行被覆盖到了

image.png

默认情况下,coverage生成的结果文件为.coverage,你可以通过修改环境变量COVERAGE_FILE来修改这个文件的后缀名。你也可以是用-a把多次运行的结果合并到一个文件里,否则,每次生成的结果文件都是上一次运行的结果。你可以是用coverage erase清空之前运行的结果文件。

coverage threshold

covearge可以使用参数--fail-under指定一个数字,当coverage的结果小于这个数字,coverage命令返回一个错误码2,但这个参数对annotate命令无效

$ coverage run run_my_tests.py

... running all tests

$ coverage report --fail-under=100

... display the report

$ echo $?

2

如果覆盖率不是100%,则返回值是2。也可以通过python api来验证覆盖率,示例如下:

cov = coverage.coverage(..)

cov.start()

ret = run_all_my_tests()

cov.stop()

if ret == 0:

covered = cov.report()

assert covered > 100, "Not enough coverage"

unittest框架

unittest 框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:09,AZ,a~z 如果要让某个测试用例先执行,不能使用默认的main()方法,需要通过TestSuite类的addTest()方法按照一定的顺序来加载

如果需要,用户可以自己实现discover(),遍历目录并添加和组合测试用例。利用discover获取指定目录或多级目录下的测试用例,但存放用例的目录属性必须是python package,必须要有init.py,不然不会获取成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值