2016-07-20 10 views
1

ほとんど同じ設定が必要なpytestテストケースがいくつかありますので、DRYを維持するためにフィクスチャを再利用するようにしたいと思います。この設定では、外部のチケット追跡システムに新しいチケットを作成し、そのテストケースをデータに基づいてチケットとやりとりし、最終的にチケットをクローズして治具をクリーンアップします。ここで問題となるのは、各テストケースでは、チケットに用意されるデータが少しずつ異なる必要があるということです。pytestでrequest.functionを使用するとAttributeErrorが発生するFixture

それぞれのテストケースは異なる呼び出しと異なるアサーションを持っているので、それらを1つのテストフィクスチャで1つのパラメータ化されたテストケースに結合することはできません。フィクスチャ自体をパラメータ化すると、すべてのテストケースがフィクスチャデータのすべての置換を実行する結果になり、無関係なテストの失敗が多くなります。

私がしたいのは、テストケースに変数を設定してから、その変数を使用してチケットを作成するときにテストデータを設定することです。私はpytest fixture docsに指定されているrequest.functionを使用しようとしたが、私は入れません:

=================================== ERRORS =================================== 
    ____________________ ERROR at setup of TestMCVE.test_stuff ___________________ 

request = <SubRequest 'ticket' for <Function 'test_stuff'>> 

    @pytest.yield_fixture 
    def ticket(request): 
>  ticket_summary = getattr(request.function, "summary") 
E  AttributeError: 'function' object has no attribute 'summary' 

tests\test_mcve.py:11: AttributeError 

私のコードは次のとおりです。

import pytest 


def ticket_system_api(summary): 
    # stub for MCVE purposes 
    return summary 


@pytest.yield_fixture 
def ticket(request): 
    ticket_summary = getattr(request.function, "summary") 
    new_ticket = ticket_system_api(summary=ticket_summary) 
    yield new_ticket 


class TestMCVE: 
    def test_stuff(self, ticket): 
     summary = 'xyz' 
     # do real things here, except MCVE 
     assert 'xyz' == ticket 

私が変える、request.node代わりのrequest.functionと同様にbinding the summary variable per this answerを使用して試してみましたsummary = 'xyz'test_stuff.summary = 'xyz'これらは同じAttributeErrorで失敗します。

どのように機能レベルのデータをフィクスチャに渡すことができますか?

+1

ステートメントは、「チケット」固定具に生じる前にここで「要約」オブジェクト – AlokThakur

+0

の作成前に実行されるだろう、 'ticket'はテスト機能よりも、最初に実行されます。フィクスチャの実行が完了すると、 'summary'が初期化されます。フィクスチャの代わりに 'ticket 'を通常の関数として使用できませんか? –

答えて

1

indirect parametrizationでこれを達成できます。 API(およびドキュメンテーション)はより親切であるかもしれませんが、あなたが望む機能はそこにあります。

あなたの例は非常に近く、マイナーな調整が必要でした。見てみましょう:

import pytest 


def ticket_system_api(summary): 
    # stub for MCVE purposes 
    return summary 


@pytest.fixture 
def ticket(request): 
    # NOTE: This will raise `AttributeError` if the fixture 
    # doesn't receive a parameter. 
    ticket_summary = request.param 
    new_ticket = ticket_system_api(summary=ticket_summary) 
    return new_ticket 


class TestMCVE: 
    @pytest.mark.parametrize('ticket', ('abc',), indirect=True) 
    def test_abc(self, ticket): 
     # do real things here, except MCVE 
     assert ticket == 'abc' 

    @pytest.mark.parametrize('ticket', ('xyz',), indirect=True) 
    def test_xyz(self, ticket): 
     # do real things here, except MCVE 
     assert ticket == 'xyz' 
関連する問題