5

私はたくさんの検索を行ってきましたが、探していたものが本当に見つかったとは思いません. 私がやろうとしていることを説明するために最善を尽くします。うまくいけば、簡単な解決策があり、何か新しいことを学べたことをうれしく思います。

これは最終的に私が達成しようとしていることです: ノーズテストを使用し、属性セレクター プラグインを使用していくつかのテスト ケースを装飾し、コマンドライン呼び出し中に -a スイッチを使用して条件に一致するテスト ケースを実行します。実行されたテストの属性値は、外部の場所に保存されます。私が使用しているコマンドライン呼び出しは以下のようなものです:

nosetests \testpath\ -a attribute='someValue'

また、テスト ケースの属性を保存し、それらを外部の場所に書き込む、カスタマイズされたノーズテスト プラグインも作成しました。アイデアは、テストのバッチを選択し、これらのテストの属性を保存することで、後でレポート目的でこれらの結果をフィルタリングできるというものです。次のようなコードで「wantMethod」メソッドをオーバーライドして、プラグインのメソッド属性にアクセスしています。

def set_attribs(self, method, attribute):
    if hasattr(method, attribute):
        if not self.method_attributes.has_key(method.__name__):
            self.method_attributes[method.__name__] = {}

        self.method_attributes[method.__name__][attribute] = getattr(method, attribute)

def wantMethod(self, method):
    self.set_attribs(method, "attribute1")
    self.set_attribs(method, "attribute2")
    pass

テストが「yield」キーワードを使用している1つのケースを除いて、ほとんどすべてのテストでこれが機能しています。何が起こっているかというと、生成されたメソッドは正常に実行されていますが、生成された各関数のメソッド属性は空です。

以下は、私が達成しようとしているものの例です。以下のテストは、値のリストを取得し、それらの値のそれぞれについて、別の関数からの結果を生成します。

@attr(attribute1='someValue', attribute2='anotherValue')
def sample_test_generator(self):
    for (key, value) in _input_dictionary.items()
        f = partial(self._do_test, key, value)
        f.attribute1='someValue'
        yield (lambda x: f(), key)

def _do_test(self, input1, input2):
    # Some code

私が読んだことから、そして私が理解していると思うと、yieldが呼び出されると、新しい呼び出し可能な関数が作成され、それが実行されます。sample_test_generator メソッドから属性値を保持する方法を見つけようとしましたが、うまくいきませんでした。部分的なメソッドを作成して、メソッドに属性を追加できると思ったのですが、うまくいきませんでした。テストはまったくエラーなしで実行されます。プラグインの観点からは、メソッド属性が存在しないため、記録されないようです。

これはかなり複雑な質問だと思いますが、私が達成しようとしていることの背景が明確であることを確認したかったのです。今回のケースで参考になる情報を探していたのですが、つまずきを感じているので、専門家の方にアドバイスをお願いしたいと思います。

ありがとう。

** アップデート **

フィードバックを読み、もう少し遊んだ後、ラムダ式を変更すると、探しているものが実現するようです。実際、部分関数を作成する必要さえありませんでした。

def sample_test_generator(self):
    for (key, value) in _input_dictionary.items()
        yield (lambda: self._do_test)

このアプローチの唯一の欠点は、テスト名が変更されないことです。私がもっと遊んでいると、ノーズテストのように見えます。テストジェネレーターを使用すると、含まれるキーワードに基づいて結果のテスト名が実際に変更されます。パラメータでラムダ式を使用していたときにも同じことが起こっていました。

例えば:

  1. パラメータ付きのラムバ式の使用: yield (lambda x: self._do_test, "value1")

ノーズテスト プラグインでは、テスト ケース名にアクセスすると、「sample_test_generator(value1)」と表示されます。

  1. パラメーターなしでラムダ式を使用する: yield (lambda: self._do_test)

この場合のテスト ケース名は「sample_test_generator」になります。上記の例では、ディクショナリに複数の値がある場合、yield 呼び出しが複数回発生します。ただし、テスト名は常に「sample_test_generator」のままです。これは、一意のテスト名を取得する場合ほど悪くはありませんが、属性値をまったく保存できません。引き続き遊んでいきますが、これまでのフィードバックに感謝します!

編集

戻ってきて、これを最終的に機能させる方法についての最終更新を提供するのを忘れていました。最初は少し混乱しました。テストがどのように認識されるかについて:

私の最初の実装では、実行のために取得されるすべてのテストが、プラグインの基本クラスからの「wantMethod」呼び出しを通過すると想定していました。これは、「yield」を使用してテストを生成する場合には当てはまりません。この時点で、テスト メソッドは「wantMethod」呼び出しをすでに通過しているためです。

ただし、「yeild」呼び出しによってテスト ケースが生成されると、プラグイン基本クラスからの「startTest」呼び出しが実行され、ここでようやく属性を正常に格納できました。

つまり、私のテスト実行順序は次のようになります。

ノーズ -> wantMethod(method_name) -> yield -> startTest(yielded_test_name)

私の startTest メソッドのオーバーライドには、次のものがあります。

def startTest(self, test):
    # If a test is spawned by using the 'yield' keyword, the test names would be the parent test name, appended by the '(' character
    # example:  If the parent test is "smoke_test", the generated test from yield would be "smoke_test('input')
    parent_test_name = test_name.split('(')[0]

    if self.method_attributes.has_key(test_name):
        self._test_attrib = self.method_attributes[test_name]
    elif self.method_attributes.has_key(parent_test_name):
        self._test_attrib = self.method_attributes[parent_test_name]
    else:
        self._test_attrib = None

この実装では、wantMethod のオーバーライドとともに、親テスト ケースによって生成された各テストも親メソッドから属性を継承します。これは私が必要としていたものです。

繰り返しますが、返信を送ってくれたすべての人に感謝します。これはかなりの学習経験でした。

4

2 に答える 2

0

これは機能しますか?

@attr(attribute1='someValue', attribute2='anotherValue')
def sample_test_generator(self):
    def get_f(f, key):
        return lambda x: f(), key
    for (key, value) in _input_dictionary.items()
        f = partial(self._do_test, key, value)
        f.attribute1='someValue'
        yield get_f(f, key)

def _do_test(self, input1, input2):
    # Some code

問題は、ラムダを作成した後にローカル変数が変更されることです。

于 2013-01-14T21:49:47.443 に答える
0

これで名前の問題は解決しますか?

def _actual_test(x, y):
    assert x == y

def test_yield():
    _actual_test.description = "test_yield_%s_%s" % (5, 5)
    yield _actual_test, 5, 5

    _actual_test.description = "test_yield_%s_%s" % (4, 8)  # fail
    yield _actual_test, 4, 8

    _actual_test.description = "test_yield_%s_%s" % (2, 2)
    yield _actual_test, 2, 2

名前の変更も生き残り@attrます。

于 2012-12-12T14:02:21.890 に答える