如何忽略 nose-tests 覆盖中的 PonyORM 生成器表达式

How to ignore PonyORM generator expressions in nose-tests coverage

我正在使用 nosetests --cover-erase --with-cover --cover-branches 来 运行 我的测试用例。

我正在使用 PonyORM 删除一组对象。下面是我的代码的样子。

@db_session
def remove_all_stuff(self):
    delete(j for j in MyEntityClass if j.deleted == True)

当我计算覆盖率时,即使我执行remove_all_jobs。 PonyORM 不会在 delete(.

中执行生成器表达式

如何忽略生成器表达式并仍然检查是否调用了 delete(


我发现了什么。

  1. # pragma: no cover -> 无法使用,因为我需要覆盖 delete
  2. [report] exclude_lines in .coveragerc 也不适用于这种情况。

在这种情况下,您可以使用 # pragma: no branch 指令。这将忽略生成器表达式。

@db_session
def remove_all_stuff(self):
    delete(j for j in MyEntityClass if j.deleted == True)  # pragma: no branch

如果您使用 lambda 到 select,请将它们格式化为新行并使用 # pragma: no cover

为什么会这样?

这是因为 PonyORM 不执行生成器表达式,有时不执行 lambda。它通过对这些python个表达式的抽象语法树进行反编译分析,生成SQL

更多信息:How Pony (ORM) does its tricks?

我在 coverage.py issue about this 中添加了一些其他建议。


如何更优雅地处理这个问题的其他一些可能性:

您可以设置 coverage.py pragma regex 以便某些行自动 pragma'd:

[report]
partial_branches = 
    pragma: no branch
    \.select\(lambda

现在,任何与这两个正则表达式中的任何一个匹配的行都将被视为部分分支,因此即使没有注释,您的行也会被识别。

您可以将 lambda 或生成器表达式的定义与使用它们的行分开:

to_select = lambda p: p.nom_d_exercice.lower().startswith(chaine.lower())    # pragma: no branch
return Praticien.select(to_select)

或:

to_delete = (j for j in MyEntityClass if j.deleted == True)  # pragma: no branch
delete(to_delete)

这将非 运行 代码隔离到它自己的行,因此您不会 运行 在真正需要它的行上关闭覆盖率测量的风险。