当前位置: 首页 > 知识库问答 >
问题:

如何查找覆盖范围内从未执行过的代码。尽管有100%的覆盖率报告

孟修竹
2023-03-14

考虑以下代码:

import math

def dumb_sqrt(x):
    result = math.sqrt(x) if x >= 0 else math.sqrt(-x)*j
    return result


def test_dumb_sqrt():
    assert dumb_sqrt(9.) == 3.

测试可按如下方式执行:

$ pip install pytest pytest-cov
$ pytest test_thing.py --cov=test_thing --cov-report=html --cov-branch

覆盖报告将考虑涵盖的所有第100%行,即使启用分支覆盖:

然而,这段代码有一个错误,那些有敏锐眼光的人可能已经看到了。如果它进入“其他”分支,将会有一个例外:

NameError: global name 'j' is not defined

修复该错误很容易:将未定义j名称更改为文本1j。还可以很容易地添加另一个测试来揭示错误:assert dumb_sqrt(-9.)==3j。这也不是这个问题所要问的。我想知道如何找到尽管有100%的代码覆盖率报告但从未实际执行过的代码段。

使用条件表达式就是这样一个罪魁祸首,但是在任何地方都有类似的情况,Python可以使计算短路(x或yx和y是其他例子)。

最好,上面的第4行可以在报告中被着色为黄色,类似于“如果”行如果首先避免使用条件表达式会呈现的方式:

coverage.py是否支持这样的功能?如果是,如何在您的cov报告中启用“内联分支覆盖”?如果没有,有没有其他方法来识别测试套件从未实际执行的“隐藏”代码?

共有2个答案

双弘益
2023-03-14

如果不使用res1,也不要使用res2——它必须被视为一个单独的语句。如果你把这写成如果/否则,我认为coverage.py会做得更好。

考虑使用pylint之类的东西,或者至少使用pyflakes。我相信这些会自动检测到问题。

葛景龙
2023-03-14

不,保险范围。py不处理表达式中的条件分支。这不仅影响Python条件表达式,使用也会受到影响:

# pretending, for the sake of illustration, that x will never be 0
result = x >= 0 and math.sqrt(x) or math.sqrt(-x)*j

coverage.py的维护者Ned Batchelder在2007年的一篇文章中称之为隐藏条件,该文章涵盖了coverage.py无法处理的情况。

这个问题也延伸到if语句!举个例子:

if condition_a and (condition_b or condtion_c):
    do_foo()
else:
    do_bar()

如果当条件a为真时条件b始终为真,则您永远不会在条件c中找到打字错误,如果您仅依赖于对流,则不会。py,因为不支持条件覆盖(更不用说更高级的概念,如修改的条件/决策覆盖和多条件覆盖)。

支持有条件覆盖的一个障碍是技术:覆盖。py在很大程度上依赖于Python的内置跟踪支持,但直到最近,它才允许您跟踪每行的执行情况。Ned实际上探索了解决这个问题的方法。

并不是说这阻止了一个不同的项目,不管怎样,它都有助于提供条件/决策覆盖。该项目使用AST重写和导入钩子添加额外的字节码,让它跟踪个别条件的结果,从而让您对表达式的“真值表”有一个概述。这种方法有一个巨大的缺点:它非常脆弱,并且经常需要更新新的Python版本。因此,该项目与Python3.4背道而驰,尚未修复。

然而,Python3.7增加了对操作码级别跟踪的支持,允许跟踪程序分析每个字节码的效果,而不必求助于AST黑客。而且有覆盖范围。py 5.0已达到稳定状态,项目似乎正在考虑增加对条件覆盖的支持,可能的赞助商支持开发。

所以你现在的选择是:

  • 在Python3.3中运行代码,并使用instrumental
  • 修复工具以在较新的Python版本上运行
  • 等待报道。py添加条件覆盖范围
  • 帮助编写覆盖范围的功能。py
  • 使用Python3.7或更新的“操作码”跟踪模式,将您自己版本的instrumental方法拼凑在一起

 类似资料:
  • Jacoco插件在jenkins报告中显示0%的覆盖率,但当我在本地系统中运行相同的命令时,Jacoco会正确生成报告。我正在使用以下命令: mvn-s xyz/settings.xml-f xyz/xyz/pom.xml清洁安装org.jacoco 所以当我在jenkins中运行这个命令时,它会生成错误的报告。我已经检查了它在工作区目录对应的项目在詹金斯。它显示每个项目的0%覆盖率。但是当我在本

  • 这是一个重要的可量化指标,如果代码覆盖率很高,你就可以放心的修改代码,在发版本的时候也能睡个安稳觉。否则就是拆东墙补西墙,陷入无尽的 bug 诅咒中。 那么在 OpenResty 里面如何看到代码覆盖率呢?其实很简单,使用 LuaCov 可以很方便的实现。 我们先了解下 LuaCov,这是一个针对 Lua 脚本的代码覆盖率工具,通过 luarocks 来安装: luarocks install l

  • 问题内容: 我正在使用Mocha测试我的NodeJS应用程序。我无法弄清楚如何使用其代码覆盖功能。我尝试使用Google搜索,但没有找到任何合适的教程。请帮忙。 问题答案: 您需要一个额外的库来覆盖代码,而伊斯坦布尔的强大和便捷将使您震惊。通过Mocha测试后,请尝试以下操作: 现在,只需将命令nyc放在现有测试命令的前面,例如:

  • 我正在努力为SonarQube在Azure运营模式管道中生成代码覆盖率报告。我需要此代码覆盖率报告,以便SonarQube了解单元测试中覆盖的总代码。 我在获取单元测试期间创建的报告的步骤中收到此错误消息: 我在Azure Pipeline中生成报告所遵循的步骤: 1-在“dotnet构建”步骤之后,我包含了一个带有以下参数的“dotnettest”: 2-在“dotnet测试”之后,第一步包括一

  • 我有一个Python项目,它使用pytestcov进行单元测试和代码覆盖率度量。 我的项目的目录结构是: 我使用Travis为每个签入运行,并使用codecov查看代码覆盖率结果。 正在测试的软件包提供了一个命令行界面(CLI),它从stdin读取命令并在stdout上生成输出。它以开头。 tests目录包含两种类型的测试。 第一类测试是测试单个类的传统单元测试。例如,test_表。py导入表。p

  • 很久以前,我在准备面试时遇到了这个问题,认为这是一个需要解决的有趣问题。问题是这样的:找到一组区间的覆盖范围例如-给定[1,4)、[-2,3)、[9,10):输出应该是7(区间集覆盖-2,-1,0,1,2,3,9)。 我最初的方法是迭代区间集;将每个间隔中的数字添加到已排序的链表中。如果排序列表中已存在任何数字,请跳过它。我相信这需要O(N^2)时间和O(N)空间,所以我们可能会做得更好。 或者,