2015-01-01 3 views
6

というフィクスチャを用意していますが、パラメータ化したい場合がありますが、なぜなら、私のMVCのようなデータモデルが構造化されているので、私は "モデル"クラスでできる限りテストしますが、 "コントローラ"クラスは、 "モデル"でそれを行いました。したがって、すべてのパラメータ設定でテストを実行することはコントローラでは冗長です。テストの回数とテスト時間を制限したいと思います。現在、コントローラの初期化をテストするために、18,000を超えるテストが生成され、実行には42分かかります! Travis-CI outputを参照してください。pytestの異なるテストで特定のフィクスチャのパラメータ化のみを使用します

現在、私の回避策は行うことです、そして、

# Contents of conftest.py 
import pytest 
import pandas as pd 
import numpy as np 

@pytest.fixture(scope='module', params=[2, 3], 
       ids=['2_groups', '3_groups']) 
def n_groups(request): 
    """Number of phenotype groups. 

    For testing that functions work when there's only 2 groups 
    """ 
    return request.param 

@pytest.fixture(scope='module') 
def n_groups_fixed(): 
    """Fixed number of phenotype groups (3)""" 
    return 3 

は、私がテスト用のデータを作成する備品の次のチェーンにn_groupsまたはn_groups_fixedのいずれかを渡します。 outlierspooledsamplesn_samplesおよびmetadata_phenotype_colのフィクスチャもパラメータ化されていますが、この質問の範囲外です。

# Contents of conftest.py 
@pytest.fixture(scope='module') 
def groups(n_groups): 
    """Phenotype group names""" 
    return ['group{}'.format(i + 1) for i in np.arange(n_groups)] 

@pytest.fixture(scope='module') 
def groups_fixed(n_groups_fixed): 
    """Phenotype group names""" 
    return ['group{}'.format(i + 1) for i in np.arange(n_groups_fixed)] 

@pytest.fixture(scope='module') 
def groupby(groups, samples): 
    return dict((sample, np.random.choice(groups)) for sample in samples) 

@pytest.fixture(scope='module') 
def groupby_fixed(groups_fixed, samples): 
    return dict((sample, np.random.choice(groups_fixed)) for sample in samples) 

@pytest.fixture(scope='module') 
def metadata_data(groupby, outliers, pooled, samples, 
        n_samples, 
        metadata_phenotype_col): 
    df = pd.DataFrame(index=samples) 
    if outliers is not None: 
     df['outlier'] = df.index.isin(outliers) 
    if pooled is not None: 
     df['pooled'] = df.index.isin(pooled) 
    df[metadata_phenotype_col] = groupby 
    df['subset1'] = np.random.choice([True, False], size=n_samples) 
    return df 

@pytest.fixture(scope='module') 
def metadata_data_groups_fixed(groupby_fixed, outliers, pooled, samples, 
        n_samples, 
        metadata_phenotype_col): 
    df = pd.DataFrame(index=samples) 
    if outliers is not None: 
     df['outlier'] = df.index.isin(outliers) 
    if pooled is not None: 
     df['pooled'] = df.index.isin(pooled) 
    df[metadata_phenotype_col] = groupby_fixed 
    df['subset1'] = np.random.choice([True, False], size=n_samples) 
    return df 

これらの器具のそれぞれについて*_fixedバージョンを持っているかなり面倒そうです。試験の

例のみgroups_fixedを用いて一つの「パラメータ化」テストコントローラ内n_groupsの両方のパラメータ化、および以下の広範なテストをテストデータモデル内の広範なテストであろう(これらは単に、実際のテストではありませんデモンストレーションの例):

# Contents of test_model.py 
class TestModel(object): 
    def test__init(metadata_data, ...): 
     ... 

    def test_plot(metadata_data_fixed, ...); 
     ... 

# Contents of test_controller.py 
class TestController(object): 
    def test__init(metadata_data_fixed, ...): 
     ... 

これを行う別の方法はありますか?私はpytestのparameterizeのドキュメントを読んだことがありますが、これはテストごとではなく、グローバルにパラメータ化を設定しているようです。

私のような何かをしたい:私は

# Contents of test_controller.py 
class TestController(object): 
    @pytest.fixture 
    def n_groups(): 
     return 3 

    def test__init(metadata_data_fixed, ...): 
     ... 

# Contents of test_model.py 
class TestModel(object): 
    def test__init(metadata_data, ...): 
     ... 

    @pytest.mark.parameterize(n_groups=3) 
    def test_plot(metadata_data, ...); 
     ... 

# Contents of test_controller.py 
class TestController(object): 
    @pytest.mark.parameterize(n_groups=3) 
    def test__init(metadata_data_fixed, ...): 
     ... 

UPDATE:これは動作しません。すなわちTestControllern_groupsフィクスチャを追加すると、解決しないと理由はわかりません。なぜなら、この備品はグローバルconftest.pyに定義されたn_groupsを上書きする必要があるからです。

答えて

0

私はsurではありませんあなたが組み込みのparametrizeでそれを行うことができます、私はあなたがテストされているメソッドに関するいくつかの情報に基づいてカスタムパラメトリック化スキームを実装しなければならないと思います(たとえば、クラスにその名前にControllerが含まれていれば、 pytest_generate_tests hook。いくつかの例はhereです。

+0

ありがとうございます! 'testController'のために働くのは、' test_controller.py'ファイルでそれを持つことができ、ファイル内のすべてのテストに適用されるからです。 'TestModel'については、' metafunc.function .__ name__'を調べてそこにチェックすると思いますか?この種のものは、テスト関数用のデコレータにカプセル化することができます。そのような機能が 'pytest'で計画されているかどうか知っていますか? –

+0

はい、metafunc.function .__ name__が機能することを確認してください。しかし、これを組み込みのデコレータとして実装する計画はないと思います。 –

関連する問題