2017-07-11 10 views
2

私は特定の複雑な状態を表すクラスを持っています。その状態は変わる可能性があり、私はそのクラスの別のインスタンスが「真の」状態を表しています。私は、いくつかの論理を比較する機能を書いて、現在の状態を真の状態にする方法を見つけました。Pytestで多くのfixtueres/scenarioを持つ単一ユニットのテストケースをテストする

pytestを使用してその機能をテストしたいと思います。そこに多くのシナリオの可能性がありますが、テスト・ロジックは非常に単純で、(擬似Pythonコード)に沸く:

def test_diffing(current_state, prescribed_state): 
    properties_to_add = [] 
    properties_to_delete = [] 
    properties_to_modify = [] 
    properties_to_add, properties_to_delete, properties_to_modify = diff_logic(current_state, prescribed_state) 

    assert properties_to_add == 1 
    assert properties_to_delete == 0 
    assert properties_to_modify == 3 

のassertの右側の数字はcurrent_stateが何であるかに依存します。私は多くのcurrent_stateシナリオがあります。

上記のように単体テストを書くのに、current_stateがアサートの期待値と一緒に渡されるような多くのペアのフィクスチャを使用する最良の方法はありますか?

私はpytest fixturesのパラメータ化を見てきましたが、このアプローチの問題点は、デコレータを使用していて、非常に素早く、特に多数の引数と多数のテストケースで醜い*を得ることです。これは私がフィクスチャを使用するべきものではないようです。

私がきれいにしようとしていることを達成する最良の方法は何ですか?

*私は、醜いと言っています。なぜなら、デコレータへの15~20組の引数は非常に混乱しており、デコレータ自体に多くのロジックを入れているからです。

+0

私の理解が正しいならば、フィクスチャはテスト間の共通性のためであり、さまざまな入力用ではありません。あなたのケースでは、15-20のユニークなシナリオをテストしている場合は、15-20個の単体テストを書いた方が良いでしょう。 – Avantol13

+0

それは理にかなっています。何が同じ正確なロジックを複製することを避けるための最良の方法は15-20回ですか?唯一の違いは、current_stateオブジェクトとその期待値です。 – darksky

答えて

1

parametrized fixtures私はあなたが欲しいものを得るために使うことができると思います。

@pytest.fixture(params=[ 
    { 
     'current_state': 'foo', 
     'expected': { 
      'properties_to_add': 1, 
      'properties_to_delete': 2, 
      'properties_to_modify': 3, 
     }, 
    }, 
    ... as many scenarios as you'd like ... 
]) 
def bundle(request): 
    return request.param 

@pytest.fixture 
def current_state(bundle): 
    return bundle['current_state'] 

@pytest.fixture 
def expected(bundle): 
    return bundle['expected'] 

私は入力と出力を一緒に結び付けるために「バンドル」治具の構造を使用します。のようなものについてはどのように

。その後、テストは非常にきれいに見えます:

def test_diffing(current_state, expected): 
    prescribed_state = ... # I assume this is a constant, you can inject "prescribed_state" in the fixture in the same way as "current_state" and "expected" 
    properties_to_add, properties_to_delete, properties_to_modify = diff_logic(current_state, prescribed_state) 
    assert expected == { 
     'properties_to_add': properties_to_add, 
     'properties_to_delete': properties_to_delete, 
     'properties_to_modify': properties_to_modify, 
    } 

(「バンドル」治具用)「のparams」データ構造が非常に大きくなる場合次に、あなたがどこかにそれを定義し、読みやすさのためにコードをフォーマット、からそれをロードすることができますデータファイルなど

関連する問題