J'ai un code Twisted qui crée plusieurs chaînes de différés. Certains d'entre eux peuvent échouer sans avoir un errback qui les remet sur la chaîne de rappel. Je n'ai pas été en mesure d'écrire un test unitaire pour ce code - l'échec différé provoque l'échec du test une fois le code de test terminé. Comment puis-je écrire un test d'unité de passage pour ce code? Est-il prévu que chaque différé qui pourrait échouer en fonctionnement normal devrait avoir un errback à la fin de la chaîne qui le remet sur la chaîne de rappel?Comment les erreurs Twisted Deferred sans erreurs peuvent-elles être testées avec un essai?
La même chose se produit en cas d'échec de différé dans une liste différée, sauf si je crée la liste différée avec consumeErrors. C'est le cas même lorsque DeferredList est créé avec fireOnOneErrback et reçoit un errback qui le remet sur la chaîne de rappel. Y a-t-il des implications pour consumeErrors en plus de supprimer les échecs de test et la journalisation des erreurs? Est-ce que tous les différés qui peuvent échouer sans erreur peuvent être mis dans une liste différée?
tests Exemple de code exemple:
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)
Bonne réponse, mais vous pourriez aussi mentionner '--force-gc'. – Glyph
Bon appel, ajouté. –
Cela se produit également lorsque vous appelez log.err avec une instance d'échec, est-ce correct? – Chris