簡體   English   中英

當使用twisted和trial啟動兩個等效的unittest時,ReactorNotRestartable

[英]ReactorNotRestartable when launching two equivalent unittest with twisted and trial

我有兩個測試類( TrialTest1TrialTest2 )寫在兩個文件( test_trial1.pytest_trial2.py )中大多數相同(唯一的區別是類名):

from twisted.internet import reactor
from twisted.trial import unittest


class TrialTest1(unittest.TestCase):

    def setUp(self):
        print("setUp()")

    def test_main(self):
        print("test_main")
        reactor.callLater(1, self._called_by_deffered1)
        reactor.run()

    def _called_by_deffered1(self):
        print("_called_by_deffered1")
        reactor.callLater(1, self._called_by_deffered2)

    def _called_by_deffered2(self):
        print("_called_by_deffered2")
        reactor.stop()

    def tearDown(self):
        print("tearDown()")

當我完全運行每個測試時,一切都很好。 但是當我啟動它時,我有以下輸出:

setUp()
test_main
_called_by_deffered1
_called_by_deffered2
tearDown()
setUp()
test_main
tearDown()

Error
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/twisted/internet/defer.py", line 137, in maybeDeferred
    result = f(*args, **kw)
  File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 203, in runWithWarningsSuppressed
    reraise(exc_info[1], exc_info[2])
  File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 199, in runWithWarningsSuppressed
    result = f(*a, **kw)
  File "/home/kartoch/works/python/netkython/tests/test_twisted_trial2.py", line 13, in test_main
    reactor.run()
  File "/usr/lib/python2.7/site-packages/twisted/internet/base.py", line 1191, in run
    self.startRunning(installSignalHandlers=installSignalHandlers)
  File "/usr/lib/python2.7/site-packages/twisted/internet/base.py", line 1171, in startRunning
    ReactorBase.startRunning(self)
  File "/usr/lib/python2.7/site-packages/twisted/internet/base.py", line 683, in startRunning
    raise error.ReactorNotRestartable()
ReactorNotRestartable


Error
DirtyReactorAggregateError: Reactor was unclean.
DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
<DelayedCall 0x8d6482c [0.98535490036s] called=0 cancelled=0 TrialTest2._called_by_deffered1()>


Process finished with exit code 0

在第一次測試后,反應堆似乎沒有正確關閉。 有誰知道問題出在哪里? 似乎tearDown()被調用到早期(在第二次測試中_called_by_deffered1之前),也許修復將是使用deferTearDown (沒有記錄的試驗單元測試方法)。

編輯

提出的解決方案之一是刪除reactor.run()reactor.stop()因為反應器不可重啟,並且默認情況下您只有一個反應器實例用於所有測試:

class TrialTest1(unittest.TestCase):

    def setUp(self):
        print("setUp()")

    def test_main(self):
        print("test_main")
        reactor.callLater(1, self._called_by_deffered1)

    def _called_by_deffered1(self):
        print("_called_by_deffered1")
        reactor.callLater(1, self._called_by_deffered2)

    def _called_by_deffered2(self):
        print("_called_by_deffered2")

    def tearDown(self):
        print("tearDown()")

但是當刪除對這些方法的調用時,我的測試失敗而不執行_called_by_deffered方法:

setUp()
test_main
tearDown()

Error
DirtyReactorAggregateError: Reactor was unclean.
DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
<DelayedCall 0x94967ec [0.99936413765s] called=0 cancelled=0 TrialTest1._called_by_deffered1()>

setUp()
test_main
tearDown()

Error
DirtyReactorAggregateError: Reactor was unclean.
DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
<DelayedCall 0x94968cc [0.99958896637s] called=0 cancelled=0 TrialTest2._called_by_deffered1()>

如果我只想在測試之間只使用一個reactor共享實例,那么_called_by_deffered方法如何成為測試的一部分( tearDown之前執行)?

反應堆不可重啟。 您可以通過兩種明顯的選擇來編寫測試。

一個是使用全球反應堆。 試驗開始和停止 - 你的測試永遠不必調用reactor.runreactor.stop (他們永遠不應該)。 它可以from twisted.internet import reactor以通常的方式訪問。

另一種是每次測試使用一個新的反應堆實例。 有在一些面向測試的反應器實例twisted.test.proto_helpers (即只有部分twisted.test這是一個公開的,支撐的方式接口)。 MemoryReactorStringTransport使您能夠測試網絡交互的大部分方式。 twisted.internet.task.Clock幫助您測試基於時間的事件。

在Jean-Paul的幫助下, 這個頁面這個問題 ,我已經能夠使用twisted.internet.task.deferLater()解決問題了。 總結我正在尋找的觀點:如果一個測試方法返回一個延遲,只有當所有延遲被觸發時才會調用'tearDown()'方法。

這是代碼:

from twisted.trial import unittest
from twisted.internet import reactor, task


class TrialTest1(unittest.TestCase):

    def setUp(self):
        print("setUp()")

    def test_main(self):
        print("test_main()")
        return task.deferLater(reactor, 1, self._called_by_deffered1)

    def _called_by_deffered1(self):
        print("_called_by_deffered1()")
        return task.deferLater(reactor, 1, self._called_by_deffered2)

    def _called_by_deffered2(self):
        print("_called_by_deffered2()")

    def tearDown(self):
        print("tearDown()")

輸出:

setUp() 
test_main()

// (1s wait)

_called_by_deffered1()

// (1s wait)

_called_by_deffered2()
tearDown()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM