Есть ли способ заставить py.test игнорировать SystemExit, возникший в дочернем процессе?

Я тестирую модуль Python, который содержит следующий фрагмент кода.

        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
  • Python 2.7.6
  • pytest 2.5.2

Спасибо:)

3 ответа

Решение

(отвечая на мой вопрос)

Вы можете прекратить выполнение, не вызывая сигналов, связанных с этими событиями. Итак, вместо sys.exit(n)использовать os._exit(n), где n желаемый код состояния

Пример:

import os
os._exit(0)

credits: Есть ли способ предотвратить перехват исключительной ситуации SystemExit, вызванной sys.exit()?

def test_mytest():

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

    assert(True)

Я нашел это здесь.

Вот как я решаю проблему с макетом - при таком подходе вы можете воспользоваться всеми средствами очистки sys.exit сделает для нас

@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
Другие вопросы по тегам