4

テスト スイートを作成していますが、テストしているコードは遅延モジュール インポートを過度に使用しています。したがって、同じメソッドへの 5 つの異なる入力で、5 つの追加モジュールをインポートすることになる可能性があります。私ができるようにしたいのは、テストをセットアップして、1 つの入力でメソッドを実行すると 1 つのインポートが発生し、他の 4 つのインポートは発生しないと断言できるようにすることです。

これに着手する方法についていくつかのアイデアがありましたが、これまでのところ成功していません。すでにカスタム インポーターがあり、ロギング コードをインポーターに入れることができます。ただし、インポート ステートメントは 1 回しか実行されないため、これは機能しません。モジュールが以前にインポートされたかどうかに関係なく、ログステートメントを実行する必要があります。del sys.modules['modname']テストコードで実行され、テスト中のコードでモジュールをリロードできないため、実行するだけでも機能しません。

次に試したdictのは、監視を行うためのサブクラス化で、sys.modules をこのサブクラスに置き換えました。このサブクラスには再実装された__getitem__メソッドがありますが、呼び出しによってサブクラスimport moduleの呼び出しがトリガーされないようです__getitem__sys.modules.__getitem__また、読み取り専用であるため、に直接割り当てることもできません。

私がやろうとしていることは可能ですか?

アップデート

nneonneo の答えは、実装logImports()が使用されているモジュールと同じモジュールにある場合にのみ機能するようです。この機能を含むベース テスト クラスを作成すると、問題が発生します。__import__1つ目は、次のエラーが発生して、が見つからないことです。

#     old_import = __import__
# UnboundLocalError: local variable '__import__' referenced before assignment

それを に変更すると__builtin__.__import__、別のエラーが発生します。

myunittest.py:

import unittest
class TestCase(unittest.TestCase):
    def logImports(self):
        old_import = __builtins__.__import__
        def __import__(*args, **kwargs):
            print args, kwargs
            return old_import(*args, **kwargs)

        __builtins__.__import__ = __import__

test.py:

import myunittest
import unittest
class RealTest(myunittest.TestCase):
    def setUp(self):
        self.logImports()
    def testSomething(self):
        import unittest
        self.assertTrue(True)
unittest.main()

#     old_import = __builtins__.__import__
# AttributeError: 'dict' object has no attribute '__import__'
4

2 に答える 2

4

試す

old_import = __import__
def __import__(*args, **kwargs):
    print args, kwargs
    return old_import(*args, **kwargs)

__builtins__.__import__ = __import__

これは完全にオーバーライド__import__され、のすべての呼び出しを監視できるようになりますimport

于 2012-09-17T22:33:20.520 に答える