Tengo un código Twisted que crea múltiples cadenas de Deferreds. Algunos de estos pueden fallar sin tener un error que los vuelva a poner en la cadena de devolución de llamada. No he podido escribir una prueba unitaria para este código; el error diferido hace que la prueba falle después de que se haya completado el código de prueba. ¿Cómo puedo escribir una prueba de unidad de paso para este código? ¿Se espera que cada Deferred que podría fallar en la operación normal tenga un error al final de la cadena que lo vuelva a poner en la cadena de devolución de llamada?¿Cómo se pueden probar los errores de Twisted Deferred sin errores con prueba?
Lo mismo ocurre cuando hay un Deferred diferido en una Lista diferida, a menos que cree la Lista diferida con consumirErrores. Este es el caso incluso cuando DeferredList se crea con fireOnOneErrback y recibe un error que lo coloca de nuevo en la cadena de devolución de llamada. ¿Hay alguna implicación para consumirErrores además de suprimir las fallas de prueba y el registro de errores? ¿Debería cada Deferred que puede fallar sin un error colocarse una Lista Diferida?
ejemplo prueba de ejemplo de código:
from twisted.trial import unittest
from twisted.internet import defer
def get_dl(**kwargs):
"Return a DeferredList with a failure and any kwargs given."
return defer.DeferredList(
[defer.succeed(True), defer.fail(ValueError()), defer.succeed(True)],
**kwargs)
def two_deferreds():
"Create a failing Deferred, and create and return a succeeding Deferred."
d = defer.fail(ValueError())
return defer.succeed(True)
class DeferredChainTest(unittest.TestCase):
def check_success(self, result):
"If we're called, we're on the callback chain."
self.fail()
def check_error(self, failure):
"""
If we're called, we're on the errback chain.
Return to put us back on the callback chain.
"""
return True
def check_error_fail(self, failure):
"""
If we're called, we're on the errback chain.
"""
self.fail()
# This fails after all callbacks and errbacks have been run, with the
# ValueError from the failed defer, even though we're
# not on the errback chain.
def test_plain(self):
"""
Test that a DeferredList without arguments is on the callback chain.
"""
# check_error_fail asserts that we are on the callback chain.
return get_dl().addErrback(self.check_error_fail)
# This fails after all callbacks and errbacks have been run, with the
# ValueError from the failed defer, even though we're
# not on the errback chain.
def test_fire(self):
"""
Test that a DeferredList with fireOnOneErrback errbacks on failure,
and that an errback puts it back on the callback chain.
"""
# check_success asserts that we don't callback.
# check_error_fail asserts that we are on the callback chain.
return get_dl(fireOnOneErrback=True).addCallbacks(
self.check_success, self.check_error).addErrback(
self.check_error_fail)
# This succeeds.
def test_consume(self):
"""
Test that a DeferredList with consumeErrors errbacks on failure,
and that an errback puts it back on the callback chain.
"""
# check_error_fail asserts that we are on the callback chain.
return get_dl(consumeErrors=True).addErrback(self.check_error_fail)
# This succeeds.
def test_fire_consume(self):
"""
Test that a DeferredList with fireOnOneCallback and consumeErrors
errbacks on failure, and that an errback puts it back on the
callback chain.
"""
# check_success asserts that we don't callback.
# check_error_fail asserts that we are on the callback chain.
return get_dl(fireOnOneErrback=True, consumeErrors=True).addCallbacks(
self.check_success, self.check_error).addErrback(
self.check_error_fail)
# This fails after all callbacks and errbacks have been run, with the
# ValueError from the failed defer, even though we're
# not on the errback chain.
def test_two_deferreds(self):
# check_error_fail asserts that we are on the callback chain.
return two_deferreds().addErrback(self.check_error_fail)
Una gran respuesta, pero es posible que también desee mencionar '--force-gc'. – Glyph
Buena llamada, agregada. –
Esto también ocurre cuando se llama a log.err con una instancia de falla, ¿correcto? – Chris