py.测试:如何自动检测子进程中的异常?

2024-10-01 15:43:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我在跑步py.测试在Linux上,在大量使用多处理的模块的上下文中。子进程中的异常不会被检测为错误。示例测试文件pytest_mp_test.py

import multiprocessing

def test_mp():
    p = multiprocessing.Process(target=child)
    p.start()
    p.join()

def child():
    assert False

执行:

^{pr2}$

未检测到错误。当用-s调用时,将打印异常:

$ py.test -s pytest_mp_test.py 
================================== test session starts ===================================
platform linux2 -- Python 2.7.3 -- pytest-2.3.3
plugins: cov
collected 1 items 

pytest_mp_test.py Process Process-1:
Traceback (most recent call last):
  File "/apps11/bioinfp/Python-2.7.3/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/apps11/bioinfp/Python-2.7.3/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "/home/bioinfp/jang/hobbyproggorn/gevent-messagepipe/gevent-messagepipe/pytest_mp_test.py", line 9, in child
    assert False
AssertionError: assert False
.

================================ 1 passed in 0.04 seconds ================================

当我手动查看测试日志时,我意识到什么时候有问题。但是,我想知道是否有一种简单的方法可以在一个py测试.

我必须在父级中验证子级的退出代码吗?这是唯一的办法吗?在


Tags: inpytestselffalsechildpytest错误
2条回答

经过进一步的考虑,我认为仅仅捕捉子对象中的预期异常并检查子进程的退出状态是一个非常干净可靠的解决方案,它不会向测试添加额外的IPC组件。示例代码:

import multiprocessing
from py.test import raises

class CustomError(Exception):
    pass

def test_mp_expected_fail():
    p = multiprocessing.Process(target=child_expected_fail)
    p.start()
    p.join()
    assert not p.exitcode

def test_mp_success():
    p = multiprocessing.Process(target=child)
    p.start()
    p.join()
    assert not p.exitcode

def test_mp_unexpected_fail():
    p = multiprocessing.Process(target=child_unexpected_fail)
    p.start()
    p.join()
    assert not p.exitcode


def child_expected_fail():
    with raises(CustomError):
        raise CustomError

def child_unexpected_fail():
    raise TypeError

def child():
    pass

执行:

^{pr2}$
import pytest

@pytest.fixture
def runproc(request):
    import multiprocessing
    def Process(target):
        p = multiprocessing.Process(target=target)
        p.start()
        p.join()
        return p
    return Process

class CustomError(Exception):
    pass


def test_mp_expected_fail(runproc):
    p = runproc(child_expected_fail)
    assert not p.exitcode

def test_mp_success(runproc):
    p = runproc(target=child)
    assert not p.exitcode

def test_mp_unexpected_fail(runproc):
    p = runproc(child_unexpected_fail)
    assert not p.exitcode

def child_expected_fail():
    with pytest.raises(CustomError):
        raise CustomError

def child_unexpected_fail():
    raise TypeError

def child():
    pass

如果你把这个“runproc”装置放到一个conftest.py您可以在项目中的任何函数中接受“runproc”。在

相关问题 更多 >

    热门问题