twisted.python.log и trial - веселимся вместе

Следующий забавный случай взаимодействия частей Twisted Framework заставил меня потерять час времени, спешу рассказать, в надежде, что это спасет чьё-то время. Итак, в Twisted есть модуль логгинга, twisted.python.log, в котором есть удобный метод log.err(), который позволяет записать в лог информацию о текущем исключении. А trial - это framework для написания юнит-тестов из того же Twisted. Их сочетание иногда приводит к проблеме :)

Итак, у меня был блок кода, похожий на пример ниже:

from twisted.python import log

def catcher(f): try: return f() except GoodException: return 'ERROR' except: log.err() raise UnknownException

По смыслу он должен был логировать все неожиданные исключения и заменять их на более разумные. Я написал юнит-тест на такую функцию примерно следующего вида:


def testCatcher():
  def raiseBadException():
    assert False 
  self.assertEquals('ERROR', catcher, raiseBadException)

При запуске юнит-тест говорил, что он завершился с ошибкой, т.к. было выброшено исключение

exceptions.AssertionError, т.е. то исключение, которое генерирует строка 3 в тесте. Но ведь оно было поймано catcher? Я долго бился с этой ситуацией (на самом деле код был сложнее, но суть его от этого не менялась), пока не понял, что если из-под trial (запускальщика юнит-тестов) сделать twisted.python.log.err, то вместо того, чтобы вывести в лог исключение, он помечает тест как ошибочный, при этом в качестве причины ошибки выводит текущее исключение! То есть тест отрабатывал штатно, но log.err() мой помечал его как ошибочный.

Вот такое вот не совсем очевидное взаимодействие...

Update: на самом деле "правильный" способ это исправить - использовать TestCase.flushLoggedErrors. Спасибо @paaleksey за наводку.

Comments

Comments powered by Disqus
Contents © 2015 Andrey - Powered by Nikola