如何用Pytest测试sys.exit的指定错误消息?
问题根源分析
你当前测试失败的核心原因是mock的副作用设置错误:
- 你给
mock_open设置的side_effect = SystemExit,这会让open直接抛出SystemExit,根本不会进入代码中捕获FileNotFoundError的分支,自然不会执行sys.exit('Invalid input file \n')这行代码。 - 你捕获到的
SystemExit是mock直接抛出的,没有携带任何消息,所以才会出现断言空字符串的情况。
正确的测试方法
要验证sys.exit的错误消息,必须让代码触发FileNotFoundError,从而进入except块执行带消息的sys.exit。以下是两种正确的实现方式:
方法1:使用pytest.raises的match参数
@patch('project.open') def test_read_data_exit_message_match(mock_open): # 让open抛出FileNotFoundError,触发代码中的except分支 mock_open.side_effect = FileNotFoundError # 用match匹配错误消息(支持正则,注意换行符可以用\n或转义) with pytest.raises(SystemExit, match=r'Invalid input file\s*'): read_data(['-f', 'non_existent_file.txt'])
方法2:捕获异常后断言消息内容
@patch('project.open') def test_read_data_exit_message_content(mock_open): mock_open.side_effect = FileNotFoundError with pytest.raises(SystemExit) as exc_info: read_data(['-f', 'non_existent_file.txt']) # 直接断言完整消息,或者检查包含关系 assert str(exc_info.value) == 'Invalid input file \n' # 或者忽略换行符检查 assert 'Invalid input file' in str(exc_info.value)
额外修正:错误的嵌套断言测试
你之前写的test_read_data_error_FNFE2是错误的,因为代码中已经捕获了FileNotFoundError并转为SystemExit,所以测试层面不会收到FileNotFoundError,正确的写法只需要断言SystemExit即可,不需要嵌套:
@patch('project.open') def test_read_data_triggers_system_exit_on_file_not_found(mock_open): mock_open.side_effect = FileNotFoundError with pytest.raises(SystemExit): read_data(['-f', 'cos'])
内容的提问来源于stack exchange,提问作者Maria Żukowska
相关产品推荐
相关产品推荐

