1

で問題が発生しました@unittest.skipIf(expression)。問題は、テストを開始する前に宣言されて値が割り当てられたデコレータで変数を使用し、テスト中にこの変数の値が変更されると、デコレータに古い値が含まれるようになることです。例えば:

class Settings(object):
    flag=False
class TestCase(object):

    # during the test variable is changed (in this module or another)
    Settings.flag=True

    @unittest.skipIf(Settings.flag==True)
    def test_something(self):
        ...

の値はSettings.flag、別のモジュールまたはこのモジュールで変更できます(これは問題ではありません)。どちらの場合もSetting.flag==True、呼び出し中の条件test_somethingは、すでに「True」値に変更されていますが、「False」値を取ります。それは非常に奇妙であり、私はこのメカニズムがどのように機能するかを理解していないことを認めます。このデコレータで使用されている値は、テスト中に変更できないようです。たぶん、特定の条件のときにテストをスキップする他の興味深い方法があります。これは、テスト中に変更される可能性があります。誰かがこの問題に取り組む方法を知っていますか?

4

1 に答える 1

2

はい、これは予期された動作です。関数の引数は、関数が呼び出されるときに評価されます。デコレーターは、装飾される関数が定義されたときに呼び出される関数です。したがって、フラグは装飾された関数が定義されるときにテストされます。デコレーターは、テストが何であったかを知る方法がありません。Trueor False(または、真偽の可能性が高い)のみを確認するため、後で評価するために条件を保存することはできません。

skipIf()が必要に応じて機能するには、ブール値ではなく関数 ( など)lambda: Settings.flag==Trueを使用する必要があります。その後、装飾された関数が実際に呼び出されたときに、この条件を後で評価できます。しかし、実際にはそのようには機能しません。(ただし、これはおそらく簡単に追加できる拡張機能です。)

Settings.flagの値が確立されるまで、単体テストを含むモジュールをインポートしないことで、これを回避できる場合があります。これにより、それまでテスト関数の定義 (したがって装飾) が延期され、デコレータはフラグの目的の値にアクセスできるようになります。あなたのコードがどのように構成されているかわからないので、これがあなたにとって実用的かどうかわかりません。

さらに、何かが怪しいように見えSettings.flag==Trueます...私の指を置くことはできません... ;-)

于 2012-05-09T22:32:11.237 に答える