pytest

2015-01-01 10 views
6

में विभिन्न परीक्षणों में केवल कुछ निश्चित स्थिरता पैरामीटर का उपयोग करें। मेरे पास n_groups नामक एक स्थिरता है जिसे मैं कुछ मामलों में पैरामीटर बनाना चाहता हूं, लेकिन दूसरों में नहीं। इसका कारण यह है कि जिस तरह से मेरा एमवीसी-जैसे डेटा मॉडल संरचित किया गया है, मैं "मॉडल" कक्षाओं में जितना भी कर सकता हूं, उतना परीक्षण करता हूं, लेकिन "नियंत्रक" वर्गों को परीक्षण के व्यापक रूप से आवश्यकता नहीं होती है क्योंकि मैं पहले से ही कर चुका हूं इसे "मॉडल" में किया। तो सभी पैरामीटर के साथ परीक्षण चलाना नियंत्रक में अनावश्यक है, और मैं परीक्षण की संख्या और इस प्रकार परीक्षण समय सीमित करना चाहता हूं। वर्तमान में मेरे नियंत्रक के प्रारंभिक परीक्षण के परीक्षण के लिए, 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 पारित करने के लिए है। outliers, pooled, samples, n_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 संस्करण के लिए नहीं बल्कि बोझिल लगता है।

परीक्षण के उदाहरण n_groups के दोनों parameterizations परीक्षण डेटा मॉडल के भीतर एक व्यापक परीक्षण, और नियंत्रक है, जो केवल एक "parameterization" groups_fixed का उपयोग कर परीक्षण के भीतर एक कम व्यापक परीक्षण किया जाएगा (ये वास्तविक परीक्षण, बस नहीं हैं प्रदर्शन के लिए उदाहरण):

# 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 दस्तावेज को पढ़ा है, लेकिन यह केवल वैश्विक स्तर पर पैरामीटर को सेट करता है, न कि प्रति-परीक्षण आधार पर। यानी यह काम नहीं करता, TestController के भीतर एक n_groups स्थिरता को जोड़ने में मदद नहीं करता:

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

अद्यतन:

मैं की तरह कुछ करना चाहते हैं

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

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

मैं यकीन नहीं क्यों, क्योंकि ऐसा लगता है कि इस स्थिरता को वैश्विक n_groups को conftest.py

उत्तर

0

में परिभाषित किया जाना चाहिए, मैं sur नहीं हूँ ई आप बिल्टिन parametrize के साथ ऐसा कर सकते हैं, मुझे लगता है कि आपको परीक्षण की जा रही विधि के बारे में कुछ जानकारी के आधार पर एक कस्टम पैरामीट्रिजेशन योजना लागू करनी होगी (उदाहरण के लिए, यदि किसी वर्ग में Controller नाम है तो आप इसे अलग-अलग पैरामीट्रीज़ करेंगे) pytest_generate_tests hook। कुछ उदाहरण here मिल सकते हैं।

+0

धन्यवाद! यह 'TestController' के लिए काम करता है क्योंकि मेरे पास फ़ाइल' test_controller.py' फ़ाइल में हो सकता है, और फ़ाइल में सभी परीक्षणों पर लागू होगा। 'टेस्टमोडेल' के लिए, क्या मुझे लगता है कि वहाँ देखने के लिए 'metafunc.function .__ name__' का निरीक्षण करें? ऐसा लगता है कि इस तरह की चीज परीक्षण कार्यों के लिए एक सजावट में encapsulated किया जा सकता है। क्या आपको पता है कि इस तरह की सुविधा 'pytest' में योजनाबद्ध है या नहीं? –

+0

हां, metafunc.function के लिए जाँच करें .__ name__ काम करेगा। मुझे नहीं लगता कि एक अंतर्निहित सजावटी के रूप में इसे लागू करने की कोई योजना है, हालांकि। –

संबंधित मुद्दे