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
相关产品推荐
相关产品推荐

