3

テスト目的でソケットを使用する TestCase があります。何らかのエラーが発生した場合でも常にソケットを閉じる必要があるため、ソケットを抽象化するコンテキスト マネージャー クラスを作成しました。

テスト フィクスチャは次のようになります。ここMyClassToTestで、 はソケット デバイスを内部で使用するテスト対象の実際のクラスです。

with SocketContextManager() as device:
    foo = MyClassToTest(device)
    # make tests with foo

これらの 2 つの行が各テスト フィクスチャで繰り返されるのを避けたいのですが、一貫して に配置されsetUpます。しかし、どうすればいいですか?次のコード

def setUp(self):
    with SocketContextManager() as device:
        self.foo = MyClassToTest(device)

の終了時にデバイスが閉じられるため、 は機能しませんsetUp。このようにコンテキスト マネージャーのインスタンス化を処理する方法はありますか、それともすべてのテスト フィクスチャでそれを繰り返す必要がありますか?

4

2 に答える 2

2

ティアダウンのドキュメントによると:

これは、テスト メソッドが例外を発生させた場合でも呼び出されます

したがって、 でソケットを開き、setUpで閉じることができtearDownます。テスト ケースで例外が発生した場合でも、ソケットは閉じられます。

于 2012-12-14T08:15:04.557 に答える
1

これは非常に興味深い質問です。BrenBarn が指摘したように、unittest フレームワークはあなたがやりたいことをサポートしていませんが、それを適合させることができなかった特別な理由はないように思えます。setUp/tearDownペアリングは、ジェネレーターを持たない他の言語の名残です。

以下のコードは、テスト用のコンテキストを構築および破棄する単一のジェネレーターに setUp メソッドと tearDown メソッドの両方を統合する新しい「ContextTest」クラスを定義します。他のボイラープレートと一緒にwithステートメントをメソッドにドロップできます。context()

#!/usr/bin/python3.3
import unittest

class ContextTest(unittest.TestCase):
    """A unit test where setUp/tearDown are amalgamated into a
    single generator"""
    def context(self):
        """Put both setUp and tearDown code in this generator method
        with a single `yield` between"""
        yield

    def setUp(self):
        self.__context = self.context()
        next(self.__context)
    def tearDown(self):
        for _ in self.__context:
            raise RuntimeError("context method should only yield once")

from contextlib import closing
from urllib.request import urlopen

class MyTest(ContextTest):
    def context(self):
        with closing(urlopen('http://www.python.org')) as self.page:
            yield

    def testFoo(self):
        self.assertIsNotNone(self.page)

if __name__=='__main__':
    unittest.main()
于 2012-12-14T08:58:08.517 に答える