6

我不太明白 Python 的分支覆盖率统计数据试图告诉我什么。给定表格的代码

def f(a, b):
    c = (i for i in a)
    d = (j for j in b)  # Line of interest
    return dict(zip(c, d))

print(f(['a', 'b'], [1, 2]))

它是在单元测试期间导入的,Python 的标准分支覆盖率告诉我该# Line of interest行仅被部分覆盖(n->-n在 CLI 输出中,漂亮的 html 报告中的“n ↛ exit [?]”)。

返回的 dict 被清楚地打印出来,并且使用空列表执行仍然会产生未覆盖的行。

我是否误解了覆盖率输出?这闻起来像虫子吗?

Python 3.5.1,覆盖 4.0.3

4

1 回答 1

4

我对此进行了进一步调查,我认为这不是覆盖范围的错误。当第一个生成器 ( c) 终止时,zip()有效地不会再从第二个生成器 ( d) 收集任何值,因此分支覆盖不会跟踪d运行到完成,即使每个元素都被实际提取。

如果你改为写:

def f(a, b):
    c = (i for i in a)
    d = tuple(j for j in b)  # Line of interest
    return dict(zip(c, d))

print(f(['a', 'b'], [1, 2]))

正如人们所期望的那样,即使输出相同,第二个生成器也会运行完成并且覆盖范围很广。

我不认为有一个简单的方法可以解决这个问题,即使你将生成器表达式写成包含相同 for 循环的生成器函数,你也会得到一个(稍微清晰的)错误,即执行从未跳转到函数退出。

我认为这只是对覆盖范围和生成器退出条件的限制,因为它不知道生成器是否应该退出,所以它会标记未覆盖的情况。

于 2016-02-10T20:43:12.927 回答