2

テスト間で接続をオンラインに保つ方法はありますか?

複数のテスト セットを実行しているときにユーザーをログに記録しようとしましたが、予期しない動作に気付きました: 各テストの後にリアクターが停止します (確立された接続が使用できなくなります)。

これを調べるために、サンプルのテストファイル (以下) を用意しました。

これにより、単純なリッスン エコー サーバーが作成され、クラス フィールドに格納されます。3 つのテストが実行されます。サーバーは、すべてのテスト中に適切に実行されることが期待されています (実際には、最初のテストが終了するまでしか実行されません)。

例:

#! /usr/bin/python
# -*- coding: utf-8 -*-

import logging

from twisted.python import log
from twisted.internet import defer, base, reactor
from twisted.trial import unittest
from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import TCP4ServerEndpoint

observer = log.PythonLoggingObserver()
observer.start()
logging.basicConfig(level=logging.DEBUG)

class Echo(Protocol):
    '''Protocol from twistedmatrix examples'''
    def connectionMade(self):
        log.msg('Got incomming connection')
        self.transport.write("An apple a day keeps the doctor away\r\n")

    def connectionLost(self, reason):
        log.msg('Connection lost due to: %s' % reason)

    def dataReceived(self, data):
        self.transport.write(data)
        log.msg('Got some data: %s' % data)


class EchoFactory(Factory):
    '''Factory from twistedmatrix examples'''
    def buildProtocol(self, addr):
        return Echo()


class SampleTest(unittest.TestCase):
    '''Sample test case class derived straight from twisteds TestCase'''
    is_a_first_test = True
    endppoint = None
    def logLater(self, msgg = None):
        log.msg('called later message')

    @defer.inlineCallbacks
    def setUp(self):
        if self.__class__.is_a_first_test:
            self.__class__.endpoint = TCP4ServerEndpoint(reactor, 8007)
            self.__class__.endpoint.listen(EchoFactory())
            self.__class__.is_a_first_test = False

        log.msg('setting Up ... You may try (re)connecting now!!!')
        log.msg('We have endpoint: %s' % self.endpoint)
        yield reactor.callLater(5, self.logLater)
        log.msg('setUp done')

    def tearDown(self):
        log.msg('tearDown started')
        result = defer.Deferred()
        result.addCallback(self.logLater)
        reactor.callLater(5, result.callback, 'tearDown msg')
        log.msg('leaving tearDown')
        return result

    @defer.inlineCallbacks
    def test_00(self):
        log.msg('00 test body')
        sample_defer = defer.Deferred()
        sample_defer.addCallback(self.logLater)
        reactor.callLater(5, sample_defer.callback, 'Some sample action 00')
        log.msg('waiting reactor deferred')
        yield sample_defer
        log.msg('done with test body')

    @defer.inlineCallbacks
    def test_01(self):
        log.msg('01 test body')
        sample_defer = defer.Deferred()
        sample_defer.addCallback(self.logLater)
        reactor.callLater(5, sample_defer.callback, 'Some sample action 01')
        log.msg('waiting reactor deferred')
        yield sample_defer

    @defer.inlineCallbacks
    def test_02(self):
        log.msg('02 test body')
        sample_defer = defer.Deferred()
        sample_defer.addCallback(self.logLater)
        reactor.callLater(5, sample_defer.callback, 'Some sample action 02')
        log.msg('waiting reactor deferred')
        yield sample_defer

上記のファイルを次のように実行します。

trial test-file.py

各テストの最後に「メインループが終了しました」と表示されます。その後、ポートはすべてのテストでリッスンしたままになります (netstat -n4lt による)。ただし、2回目と3回目のテストボディでtelnet接続してもエコーはありません(1回目のみ)。

Twisted doc http://twistedmatrix.com/documents/current/core/howto/testing.html#auto3のように述べています。私の twistedmatrix 登録リクエストはまだ検証されていないため、そこに質問することはできません)。

私の実際のケースでは、サーバーへの接続はテストごとに繰り返すには時間がかかりすぎるため、ケースのクラスごとに少なくとも 1 回はこれを実行したいと考えています。

では、テスト間で接続をオンラインに保つ方法はありますか?

PS python 2.7.1、python-twisted 10.2.0-1、Ubuntu 11.04 を使用

4

1 に答える 1

2

単体テストは、分離され独立していることを意図しています。ある接続で設定された接続を別の接続で使用しないでください。

グローバルリアクターは、共有された変更可能な状態の残念な部分です。単体テストでは、可能であれば、それをまったく使用しないようにする必要があります。分離と独立の補助として、試行はテスト方法間でそれを (可能な限り) リセットします。この機能を無効にすることはできません。

セットアップに費用がかかる接続があるため、その接続用に検証済みの偽物を作成することを検討する必要があります。検証済みの偽物は、実際の実装と同じように動作することを示す独自の単体テストのセットを備えた (通常) よりテストしやすい (たとえば、偽物の作成は高速である必要があります) API の代替実装です。

単体テストでは、この検証済みのフェイクを使用して、テスト メソッドごとに新しいフェイクを作成できます。これにより、分離と独立性に違反する問題が回避され、単体テストをすばやく実行できます。

于 2012-01-20T20:17:09.453 に答える