python - py.test : how to automatically detect an exception in a child process?

标签 python testing multiprocessing pytest

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

import multiprocessing

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

def child():
    assert False

执行:

$ py.test 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 .

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

未检测到错误。使用 -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.test 自动检测 child 的异常。

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

最佳答案

经过进一步考虑,我认为只捕获子项中的预期异常并检查子项的退出状态是一个非常干净可靠的解决方案,不会在测试中添加额外的 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

执行:

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

pytest_mp_test.py ..F

======================================== FAILURES ========================================
________________________________ test_mp_unexpected_fail _________________________________

    def test_mp_unexpected_fail():
        p = multiprocessing.Process(target=child_unexpected_fail)
        p.start()
        p.join()
>       assert not p.exitcode
E       assert not 1
E        +  where 1 = <Process(Process-3, stopped[1])>.exitcode

pytest_mp_test.py:23: AssertionError
------------------------------------ Captured stderr -------------------------------------
Process Process-3:
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 31, in child_unexpected_fail
    raise TypeError
TypeError
=========================== 1 failed, 2 passed in 0.07 seconds ===========================

关于python - py.test : how to automatically detect an exception in a child process?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13400546/

相关文章:

python - 在 XLS 或 CSV 文件中写入具有不同颜色的单元格的一部分

python - 将 Lock 对象传递给继承 multiprocessing.Process 的类

多线程或多处理

javascript - 如何修复单元测试 Angular 11 中的错误 "is not a function"

c++ - C/C++调试原理/核心话题

python - 为什么 firebase_admin 在运行多进程时无法解析

python - SQLite - 聚集列存储索引

python - 为什么从 WAV 文件导出的 CSV 文件比原始 WAV 文件大得多?

python - 如何获取数组中某个范围内或高于阈值的值的计数?

testing - 打开项目中包含的 xml 文件