Pytest

2015-01-01 17 views
6

'daki farklı testlerde yalnızca belirli fikstür parametrelerini kullanın Bazı durumlarda parametreleştirmek istediğim ancak diğerlerinde değil, n_groups adlı bir fikrim var. Bunun nedeni, MVC benzeri veri modelimin yapılandırılma biçimi olduğu için "model" sınıflarında olabildiğince fazla test yapıyorum, ancak "denetleyici" sınıflarının test kapsamı kadar kapsamlı olması gerekmez çünkü zaten bunu "model" içinde yaptı. Bu nedenle, tüm parametrelendirmelerle testleri çalıştırmak denetleyicide gereksizdir ve test sayısını ve dolayısıyla test süresini sınırlamak isterim. Şu anda kontrol cihazımın başlatılmasını test etmek için 18.000'den fazla test üretiliyor ve çalışmanın 42 dakikası var! Travis-CI output'a bakın. Pytest

Şu anda, benim geçici çözüm
# 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 

Sonra ben test için veri oluşturmak armatürleri sonraki zincirine n_groups veya n_groups_fixed ya geçmek yapmaktır. outliers,, samples, n_samples ve metadata_phenotype_col armatürleri de parametrelendirilmiştir, ancak bu sorunun kapsamı dışındadır.

# 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 

demirbaşlar her biri için bir *_fixed sürümüne sahip oldukça hantal görünüyor. testlerin

örnekler, bu gerçek testler sadece değildir (n_groups iki parametreler altında test veri modeli içinde geniş bir testi ve sadece groups_fixed kullanılarak bir "parametrelendirmesini" test kontrol, içinde daha az kapsamlı bir test olacaktır gösterim örnekleri):

# 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, ...): 
     ... 

Bunu yapmanın başka bir yolu var mı? Pytest'in parameterize belgesini okudum, ancak sadece test bazında değil, sadece global olarak parametrelendirmeyi ayarladım. Bu işe yaramazsa, yani TestController içinde n_groups fikstür ekleme yardımcı olmuyor:

# 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, ...): 
     ... 

GÜNCELLEME:

ben böyle bir şey yapmak istiyorum

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

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

Ben emin değilim, çünkü bu fikstür, conftest.py

cevap

0

'de tanımlanan global n_groups'un üzerine yazması gerektiği anlaşılıyor. e parametrize ile bunu yapabilirsin, sanırım test edilen yöntemle ilgili bazı bilgilere dayanarak özel bir parametrelendirme şemasını uygulaman gerekecek (örneğin, eğer bir sınıf Controller ismini farklı şekilde parametrize edeceksen) pytest_generate_tests hook. Bazı örnekler here bulunabilir.

+0

Teşekkürler! 'TestController' için çalışıyor çünkü 'test_controller.py' dosyasında bunu yapabilirim ve dosyadaki tüm sınamalara uygularım. 'TestModel' için, metafunc.function .__ name__' kontrol etmek için orada düşünürdüm? Görünüşe göre bu tür şeyler test fonksiyonları için bir dekoratörde kapsüllenebilir. Böyle bir özellik 'pytest' içinde planlanmış olup olmadığını biliyor musunuz? –

+0

Evet, metafunc.function .__ name__ için çalışacağını kontrol edin. Bununla birlikte, bunu yerleşik bir dekoratör olarak uygulamak için herhangi bir plan olduğunu düşünmüyorum. –

İlgili konular