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有错。
所以,为了简化:
Class2
通过单元测试 得到适当覆盖
Class1
没有 直接覆盖并使项目面临风险
- 当单元测试 运行 并且生成代码覆盖率报告时,它错误地显示 两个 模块以及测试
- 相反,我希望报告显示
Class2
被覆盖,因为 foo()
被测试明确调用,而 Class1
没有被覆盖,因为它的功能在 Class2.foo()
中调用
这让我想到以下问题:
- 有没有办法在覆盖率报告中防止这种情况发生?
- 如果有的话,用来指代此类保险的术语是什么?
- 是否有特定的编码模式可以帮助防止出现此问题?
谢谢!
您将需要 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 测试,另一方面,您测试 每个 功能并尝试不关心地查看其工作情况关于依赖函数是否工作。
假设我的项目中有两个 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有错。
所以,为了简化:
Class2
通过单元测试 得到适当覆盖
Class1
没有 直接覆盖并使项目面临风险- 当单元测试 运行 并且生成代码覆盖率报告时,它错误地显示 两个 模块以及测试
- 相反,我希望报告显示
Class2
被覆盖,因为foo()
被测试明确调用,而Class1
没有被覆盖,因为它的功能在Class2.foo()
中调用
这让我想到以下问题:
- 有没有办法在覆盖率报告中防止这种情况发生?
- 如果有的话,用来指代此类保险的术语是什么?
- 是否有特定的编码模式可以帮助防止出现此问题?
谢谢!
您将需要 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 测试,另一方面,您测试 每个 功能并尝试不关心地查看其工作情况关于依赖函数是否工作。