关于python:有没有办法让py.test忽略在子进程上引发的SystemExit?

Is there a way to make py.test ignore SystemExit raised on a child process?

我正在测试一个包含以下代码片段的python模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        r, w = os.pipe()
        pid = os.fork()
        if pid:
            os.close(w)        # use os.close() to close a file descriptor
            r = os.fdopen(r)   # turn r into a file object
            # read serialized object from ``r`` and persists onto storage medium
            self.ofs.put_stream(bucket, label, r, metadata)
            os.waitpid(pid, 0) # make sure the child process gets cleaned up
        else:
            os.close(r)
            w = os.fdopen(w, 'w')
            # serialize object onto ``w``
            pickle.dump(obj, w)
            w.close()
            sys.exit(0)
        return result

所有的测试都通过了,但是在sys.exit(0)方面有困难。当sys.exit(0)执行时,它会引发SystemExit,由py.test截获并在控制台中报告为错误。

我不太清楚py.test在内部做了什么,但看起来它继续进行,最终忽略了由子进程引发的此类事件。最后,所有的测试都通过了,这很好。

但是我想在控制台中有一个干净的输出。

有没有办法使py.test产生干净的输出?

供您参考:

  • Debian Jessie,内核3.12.6
  • Python2.7.6
  • 比重试验2.5.2

谢谢:)


(回答我自己的问题)

您可以终止执行,而不触发与这些事件相关联的信号。因此,使用os._exit(n),而不是sys.exit(n),其中n是所需的状态代码。

例子:

1
2
import os
os._exit(0)

信用:是否有方法阻止捕获从sys.exit()引发的SystemExit异常?


1
2
3
4
5
6
7
8
9
10
11
12
def test_mytest():

    try:
        # code goes here
        # like
        # import my_packaage.__main__
        # which can raise
        # a SystemExit
    except SystemExit:
        pass

    assert(True)

我在这里找到的。


这就是我如何用mock解决问题的方法-使用这种方法,您可以利用sys.exit将为我们做的所有清理工作

1
2
3
4
5
@mock.patch('your.module.sys.exit')
def test_func(mock_sys_exit):
    mock_sys_exit.side_effect = SystemExit("system is exiting")
    with pytest.raises(SystemExit):
        # run function that supposed to trigger SystemExit