我有一些Twisted代碼可以創建多個Deferreds鏈。其中一些可能會失敗,如果沒有errback將它們放回到回調鏈中。我無法爲此代碼編寫單元測試 - 失敗的延遲會導致測試代碼完成後測試失敗。我如何爲這段代碼編寫一個通過單元測試?預計在正常運行中可能出現故障的每個Deferred應該在鏈條末端出現錯誤,並將其放回到回調鏈上?如何在沒有errbacks的情況下對Twisted Deferred錯誤進行測試?
當DeferredList中Deferred失敗時會發生同樣的事情,除非我使用consumeErrors創建DeferredList。即使在使用fireOnOneErrback創建DeferredList並給出了將其放回到回調鏈上的errback時,情況也是如此。除了抑制測試失敗和錯誤日誌記錄之外,是否還有消耗錯誤的含義?是否每個Deferred可能失敗而沒有errback被放置一個DeferredList?
的示例代碼示例測試:
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)
很好的答案,但你可能還想提及'--force-gc'。 – Glyph 2010-07-16 03:06:17
好的電話,補充。 – 2010-07-16 18:03:31
這在使用失敗實例調用log.err時也會發生,對嗎? – Chris 2016-01-24 17:00:37