• pytest文档57-计算单元测试代码覆盖率(pytest-cov)


    前言

    我们在做测试的时候,经常遇到领导的灵魂拷问:你的测试用例覆盖率是多少,达到100%了么?你如何保证你的测试质量?
    测试用例的覆盖率如何统计呢,如何知道开发的代码,我们都测到了,不会存在漏测的情况。

    pytest-cov

    先命令行安装 pytest-cov 2.10.1版本

    pip install pytest-cov==2.10.1

    环境要求:
    1.python3.6.6 版本
    备注:其它版本没试过

    python3.6.0会遇到以下问题

    INTERNALERROR>raise CoverageException("Couldn't use data file {!r}:{}".format(self.filename, msg))
    INTERNALERROR> coverage.misc.CoverageException: Couldn't use data file'C:\Users\Desktop\Pytest\.coverage': 
    Safety level may not be changed inside a transaction
    

    解决办法:安装3.6.1以上版本

    实现功能

    在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,
    比如,代码覆盖率必须达到80%或 90%。于是乎,测试人员费尽心思设计案例覆盖代码。
    单元测试的方法有:语句覆盖/判定覆盖/条件覆盖/路径覆盖

    先看一个简单的案例,前端实现一个功能,根据接口返回的不同code值,判断支付的结果,给用户返回提示友好的信息

    前端实现功能:根据接口返回的不同code值,判断支付的结果,给用户返回提示友好的信息
    接口返回格式:
    {
        "code": 0,
        "msg": "success!",
        "data": []
    }
    
    错误码参照
    0 - 成功
    30000 - 参数错误
    30001 - 余额不足
    30002 - 达到当天最大额度
    201102 - 银行卡被冻结
    

    实现代码

    
    '''
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    接口返回格式
    {
        "code": 0,
        "msg": "success!",
        "data": []
    }
    
    错误码参照
    0 - 成功
    30000 - 参数错误
    30001 - 余额不足
    30002 - 达到当天最大额度
    201102 - 银行卡被冻结
    '''
    # pay.py
    def pay_status(result):
        '''根据接口返回code状态,给用户提示对应的结果'''
        if result.get("code") == 0:
            return "支付成功"
        elif result.get("code") == 30000:
            return "支付失败: %s" % result.get("msg")
        elif result.get("code") == 30001:
            return "支付失败: %s" % result.get("msg")
        elif result.get("code") == 30002:
            return "支付失败: %s" % result.get("msg")
        elif result.get("code") == 201102:
            return "支付失败: %s" % result.get("msg")
        else:
            return "支付失败: 系统异常,未知错误"
    

    整个项目目录结构如下

    • src 是项目的源码
    • tests 是我们写的单元测试用例
    • src和tests放同一个项目的根目录下

    用例设计

    在tests/test_pay.py下写测试用例,先只写一个支付成功的案例

    from src.pay import pay_status
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    def test_pay_success():
        result = {
                "code": 0,
                "msg": "success!",
                "data": []
            }
        assert pay_status(result) == "支付成功"
    

    运行用例

    运行用例的时候加上 --cov 参数

    pytest --cov

    运行结果

    >pytest --cov
    ================================================= test session starts =================================================
    platform win32 -- Python 3.6.6, pytest-6.0.2, py-1.9.0, pluggy-0.13.1
    rootdir: D:softpytest-demo-cov
    plugins: change-report-1.0, cov-2.10.1, html-1.19.0, metadata-1.8.0
    collected 1 item
    
    tests	est_pay.py .                                                                                              [100%]
    
    ----------- coverage: platform win32, python 3.6.6-final-0 -----------
    Name                Stmts   Miss  Cover
    ---------------------------------------
    src\__init__.py         0      0   100%
    srcpay.py             13      9    31%
    tests\__init__.py       0      0   100%
    tests	est_pay.py       4      0   100%
    ---------------------------------------
    TOTAL                  17      9    47%
    
    
    ================================================== 1 passed in 0.10s ==================================================
    

    从报告可以看出srcpay.py 的代码测试覆盖率是31%,其它文件都是100%覆盖,这就说明我们单元测试代码测试覆盖率是31%
    还有一个指标是测试用例的执行率,测试用例在test_pay.py文件,执行率是100%,说明用例全部执行了。

    coverage生成html报告

    coverage 相关参数查看,使用pytest -h

    > pytest -h
    coverage reporting with distributed testing support:
      --cov=[SOURCE]        Path or package name to measure during execution (multi-allowed). Use --cov= to not do any
                            source filtering and record everything.
      --cov-report=TYPE     Type of report to generate: term, term-missing, annotate, html, xml (multi-allowed). term, term-
                            missing may be followed by ":skip-covered". annotate, html and xml may be followed by ":DEST"
                            where DEST specifies the output location. Use --cov-report= to not generate any output.
      --cov-config=PATH     Config file for coverage. Default: .coveragerc
      --no-cov-on-fail      Do not report coverage if test run fails. Default: False
      --no-cov              Disable coverage report completely (useful for debuggers). Default: False
      --cov-fail-under=MIN  Fail if the total coverage is less than MIN.
      --cov-append          Do not delete coverage but append to current. Default: False
      --cov-branch          Enable branch coverage.
      --cov-context=CONTEXT
                            Dynamic contexts to use. "test" for now.
    

    生成html的报告

    pytest --cov --cov-report=html

    执行完成,在项目根目录会生成 htmlcov 目录

    运行 index.html 文件查看代码覆盖率

    点开srcpay.py

    想覆盖率达到100%,那得再继续写用例,让每个if分支情况都覆盖到

    指定被测代码

    如果我们想指定执行项目里面的某个模块,可以通过--cov=模块 来运行

    pytest --cov=src

    >pytest --cov=src
    ================================================= test session starts =================================================
    platform win32 -- Python 3.6.6, pytest-6.0.2, py-1.9.0, pluggy-0.13.1
    rootdir: D:softpytest-demo-cov
    plugins: change-report-1.0, cov-2.10.1, html-1.19.0, metadata-1.8.0
    collected 1 item
    
    tests	est_pay.py .                                                                                              [100%]
    
    ----------- coverage: platform win32, python 3.6.6-final-0 -----------
    Name              Stmts   Miss  Cover
    -------------------------------------
    src\__init__.py       0      0   100%
    srcpay.py           13      9    31%
    -------------------------------------
    TOTAL                13      9    31%
    
    
    ================================================== 1 passed in 0.07s ==================================================
    

    也可以指定具体的py模块名称

    pytest --cov=src.pay

    但不能写成pytest --cov=src/pay.py

  • 相关阅读:
    02-自定义CALayer
    01-CALayer的基本操作
    抽屉效果
    手势识别
    事件响应
    寻找最合适的view
    hitTest方法与PointInside方法
    02-事件的产生与传递
    OC图标+启动图
    OC多线程操作
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/13672409.html
Copyright © 2020-2023  润新知