如何在pytest中测试存在二进制文件时的FileNotFound异常
测试FileNotFoundError异常分支的实用方案
很理解你的痛点——既要保留依赖供其他测试用,又要覆盖到缺失二进制的异常分支,这里有几个靠谱的方案,按从简单到灵活排序:
方案1:直接传入不存在的二进制路径测试
如果你的模块允许外部指定二进制路径(或者可以通过参数/配置注入),最直接的方式就是写一个单独的测试用例,传入一个肯定不存在的路径,触发FileNotFoundError:
import pytest from your_module import your_function, Error def test_binary_not_found(): # 传入一个系统中绝对不存在的路径 with pytest.raises(Error) as exc_info: your_function(binary="/this/path/does/not/exist/non-existent-binary") assert str(exc_info.value) == "binary not found"
这种方式最直观,不需要依赖mock工具,适合函数本身支持配置二进制路径的场景。
方案2:用unittest.mock模拟抛出异常
如果你的函数内部硬编码了二进制路径,没法直接修改参数,那就用mock工具替换subprocess.check_output的行为,让它直接抛出FileNotFoundError:
from unittest.mock import patch import pytest from your_module import your_function, Error def test_file_not_found_via_mock(): # 注意:patch的路径要和你的模块中引用subprocess的路径一致 # 如果你的模块里是`import subprocess`,就patch"your_module.subprocess.check_output" with patch("subprocess.check_output") as mock_check: # 让mock对象抛出目标异常 mock_check.side_effect = FileNotFoundError with pytest.raises(Error) as exc_info: your_function() # 调用你的业务函数 # 验证异常信息是否正确 assert str(exc_info.value) == "binary not found" # 还可以验证mock是否被正确调用 mock_check.assert_called_once_with([binary, options])
这个方案完全不依赖真实的系统环境,适合硬编码二进制路径的场景,灵活性很高。
方案3:临时修改环境变量PATH
如果你不想用mock,也可以通过pytest的monkeypatch临时修改PATH环境变量,移除包含目标二进制的路径,让系统找不到它:
import pytest import os from your_module import your_function, Error def test_binary_not_found_via_path(monkeypatch): # 先获取当前的PATH环境变量 original_path = os.environ["PATH"] # 假设你的二进制在/usr/local/bin下,把这个路径从PATH中移除 filtered_path = ":".join( dir for dir in original_path.split(":") if dir != "/usr/local/bin" ) # 用monkeypatch临时替换PATH monkeypatch.setenv("PATH", filtered_path) # 此时调用函数会触发FileNotFoundError with pytest.raises(Error) as exc_info: your_function() assert str(exc_info.value) == "binary not found" # 不用担心,monkeypatch会在测试结束后自动恢复原来的PATH
这种方式更接近真实的“缺失依赖”场景,但需要你明确知道二进制所在的路径,适合想模拟真实环境的测试场景。
内容的提问来源于stack exchange,提问作者Karol Babioch
相关产品推荐
相关产品推荐

