如何在pytest中允许子进程调用os.fork与sys.exit而不标记测试失败?
问题
当测试用例中调用os.fork()创建子进程,并在子进程内执行sys.exit()时,pytest会捕获子进程抛出的SystemExit异常,直接将测试用例标记为失败,报错信息如下:
> sys.exit(0) E SystemExit: 0
但这种子进程主动退出的逻辑往往是有意设计的,该如何配置pytest,避免将这种情况判定为测试失败?
补充示例:以下是一个期望能通过测试的函数:
def example(): pid = os.fork() if pid == 0: # 子进程分支 # 执行操作后终止子进程 sys.exit(0) os.waitpid(pid, 0) # 父进程正常返回,无异常抛出
解决方法
最优方案:改用os._exit()终止子进程
sys.exit()本质是抛出SystemExit异常来触发退出,这个异常会被pytest的全局异常捕获机制检测到;而os._exit()会直接终止进程,不会触发Python的异常处理流程,因此pytest不会将其判定为异常。
只需将子进程中的sys.exit(0)替换为os._exit(0)即可,修改后的函数如下:
def example(): pid = os.fork() if pid == 0: # 子进程分支 # 执行操作后终止子进程 os._exit(0) os.waitpid(pid, 0)
全局忽略SystemExit(不推荐)
如果必须保留sys.exit(),可以通过pytest钩子全局忽略SystemExit异常,但这会影响所有测试用例,可能掩盖真正的问题。在项目根目录的conftest.py中添加如下代码:
import pytest def pytest_exception_interact(node, call, report): if isinstance(call.excinfo.value, SystemExit): report.outcome = "passed"
测试验证
编写测试用例调用修改后的example函数,pytest会正常判定测试通过:
def test_example(): example()
内容的提问来源于stack exchange,提问作者Helmut Grohne
相关产品推荐
相关产品推荐

