Следующий забавный случай взаимодействия частей 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