Python 代码覆盖率的更严格报告

Stricter Reporting of Python Code Coverage

假设我的项目中有两个 Python 模块:

/project
  /module1
    __init__.py [Empty]
    class1.py
  /module2
    __init__.py [Empty]
    class2.py

Class1有一些作用,但重要的是doEverythingAndGetData()。让我们假装它在执行几个内部函数时返回一个数字。

现在假设 Class2 使用 Class1,然后实现了更多功能。 Class2 只有两个函数 - __init__foo()

def foo(self):
    #Create an instance of Class1
    class1 = Class1()

    #Get some information using class1
    data = class1.doEverythingAndGetData()

    #Do some logic on the data, it doesn't matter
    result = (data + 10) * 2

    #Return the result
    return result

现在我想为 Class2 编写一个涵盖 foo().

的单元测试
def test_Class2_foo():
    #Create the Class2 object
    class2 = Class2()

    #Get the result
    bar = class2.foo()

    #Compare the value
    expectedBar = 1337
    assert expectedBar == bar, "Mismatch! {} != {}".format(expectedBar, bar)

这个单元测试是为项目编写的唯一一个单元测试。我们 运行 单元测试并生成代码覆盖率报告。

检查代码覆盖率报告后,我们将看到 Class2 得到了很好的覆盖,因为我们已经进行了单元测试并且它正在做它应该做的事情。太棒了!

但是,我们还注意到 Class1 也被很好地涵盖了,因为单元测试 涵盖了 class1.doEverythingAndGetData() 及其任何基础功能。我们的报告显示了对整个项目的精彩报​​道!发给PO,让我们早点过周末吧!

虽然这是误导。我真正希望报告显示的是 Class2 被覆盖,因为我们已经编写了可靠地覆盖模块的单元测试。我 希望它显示 Class1 被覆盖,因为我们没有任何单元测试来检查它的内部功能。它只是 假设 Class1 正常工作,如果单元测试失败,它的描述将不会很有帮助,如果 Class1 则 t运行sparent有错。

所以,为了简化:

这让我想到以下问题:

  1. 有没有办法在覆盖率报告中防止这种情况发生?
  2. 如果有的话,用来指代此类保险的术语是什么?
  3. 是否有特定的编码模式可以帮助防止出现此问题?

谢谢!

您将需要 mock 来自 class1.doEverythingAndGetData() 的数据。在您当前的实现中,每当您为 class2 调用单元测试时,该函数内的 actual 代码为 运行。这样的事情会对你有所帮助,

from mock import patch
import class1

@patch('class1.doEverythingAndGetData')
def test_Class2_foo(self, doEverythingAndGetData):
    # Let's assume we are mocking 10 as the return value
    doEverythingAndGetData.return_value = 10

    class2 = Class2()

    # This will take mocked value in its implementation
    bar = class2.foo()

    #Compare the value
    expectedBar = 1337
    assert expectedBar == bar, "Mismatch! {} != {}".format(expectedBar, bar)

现在您可以为 class1.doEverythingAndGetData() 编写单独的 unittest 并获得正确的覆盖率报告!

所以回答你的 3 个问题,

Is there a way to prevent this from happening in the coverage report?

Is there a particular coding pattern that helps prevent this issue?

是的!使用 mock.

What, if any, is the term to use to refer to this type of coverage?

从某种意义上说,您所做的可以参考 integration tests, where you test a number of functions together against a series of input combinations. In unit 测试,另一方面,您测试 每个 功能并尝试不关心地查看其工作情况关于依赖函数是否工作。