首页 > 解决方案 > 单行 if 语句的覆盖范围

问题描述

Python 的静态代码分析器在以下情况下不会生成分支(单行 if)。这是设计使然吗?即使coverage只测试一种情况,Even 也能提供 100% 的覆盖率。

x = 1 if q == 0 else 10

任何人都可以对此有所了解吗?

标签: pythonif-statementpytestcoverage.py

解决方案


第一条评论说“不创建控制结构”。我不知道那是什么意思。不管是一行还是多行,编译出来的字节码都差不多:

>>> import dis
>>> def one_line():
...     x = 1 if q == 0 else 10
...
>>> dis.dis(one_line)
  2           0 LOAD_GLOBAL              0 (q)
              2 LOAD_CONST               1 (0)
              4 COMPARE_OP               2 (==)
              6 POP_JUMP_IF_FALSE       12
              8 LOAD_CONST               2 (1)
             10 JUMP_FORWARD             2 (to 14)
        >>   12 LOAD_CONST               3 (10)
        >>   14 STORE_FAST               0 (x)
             16 LOAD_CONST               0 (None)
             18 RETURN_VALUE
>>> def multi_line():
...     if q == 0:
...         x = 1
...     else:
...         x = 10
...
>>> dis.dis(multi_line)
  2           0 LOAD_GLOBAL              0 (q)
              2 LOAD_CONST               1 (0)
              4 COMPARE_OP               2 (==)
              6 POP_JUMP_IF_FALSE       14

  3           8 LOAD_CONST               2 (1)
             10 STORE_FAST               0 (x)
             12 JUMP_FORWARD             4 (to 18)

  5     >>   14 LOAD_CONST               3 (10)
             16 STORE_FAST               0 (x)
        >>   18 LOAD_CONST               0 (None)
             20 RETURN_VALUE
>>>

coverage.py 无法告诉您单行案例的原因是因为 Python 使用跟踪函数来告诉 coverage.py 发生了什么。为执行的每一行调用跟踪函数。跟踪函数不会获取一行内的事件。

此处对改进此问题的可能方法进行了更全面的讨论:https ://github.com/nedbat/coveragepy/issues/509


推荐阅读