You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pytest用例全部通过但覆盖率报第16行未覆盖问题咨询

src.py第16行未被测试覆盖的原因

首先明确行号对应关系,src.py代码按行计数如下,第16行就是abc函数else分支下、a(u)返回假值时的return 3逻辑:

# 行号标注
1  def a(s):
2      if s == 1:
3          return True
4      if s == 2:
5          return False
6      return 3
7
8  def abc(u):
9      if u ==1:
10         if a(u):
11             return 1
12     else:
13         if a(u):
14             return 2
15         else:
16             return 3

未覆盖的核心原因有两点:

  • 你对pytest-mock的side_effect传列表的生效逻辑理解错了。@pytest.mark.parametrize装饰的每个用例都是独立执行的,每个用例运行时都会重新执行mocker.patch生成全新的mock对象,side_effect也会重置为你写的初始值[True, False]。你每个用例里只调用了一次src.a,所以每次都只会取列表里的第一个值True,从来没触发过a(u)返回False的场景,自然走不到第16行的return逻辑。
  • 你的测试用例预期值本身写错了。当u=2走else分支时,如果a(u)返回False应该返回3(也就是第16行逻辑),但你给u=2的用例写的预期返回值是2,配合mock每次返回True,刚好让这个错误用例通过了,完全跳过了第16行的分支。

另外你写的s.assert_called_once_with(input_data)断言能全部通过也很正常——每个用例确实只调用了一次a,这个断言根本校验不出分支没覆盖的问题。

修正方法

调整test_abc的参数化逻辑,给每个用例单独匹配对应mock返回值,覆盖全部分支即可:

@pytest.mark.parametrize("input_data, mock_a_return, expected", [
    (1, True, 1),   # 覆盖u==1且a返回True的分支
    (2, False, 3),  # 覆盖else分支a返回False,也就是第16行逻辑
    (3, True, 2)    # 覆盖else分支a返回True的分支
])
def test_abc(input_data, mock_a_return, expected, mocker):
    s = mocker.patch('src.a', return_value=mock_a_return)
    assert src.abc(input_data) == expected
    s.assert_called_once_with(input_data)

调整后再跑覆盖率,第16行就会被覆盖到。

内容的提问来源于stack exchange,提问作者gh0st

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:48:20