2015-01-19 24 views
6

मैं Parameterizing a fixture सुविधा के बारे में बात कर रहा हूं जो एक स्थिरता को हार्ड-कोडित सेट पैरामीटर के लिए कई बार चलाने की अनुमति देता है।पाइटेस्ट स्थिरता में पैरामीटर को पारित करने का कोई तरीका?

मैं परीक्षण ऐसे ही एक पैटर्न का पालन का एक बहुत है:

httpcode = 401 # this is different per call 
message = 'some message' # this is different per call 
url = 'some url' # this is different per call 


mock_req = mock.MagicMock(spec_set=urllib2.Request) 
with mock.patch('package.module.urllib2.urlopen', autospec=True) as mock_urlopen, \ 
    mock.patch('package.module.urllib2.Request', autospec=True) as mock_request: 
    mock_request.return_value = mock_req 
    mock_urlopen.side_effect = urllib2.HTTPError(url, httpcode, message, {}, None) 
    connection = MyClass() 
    with pytest.raises(MyException): 
     connection.some_function() # this changes 

अनिवार्य रूप से, मैं एक वर्ग एक API ग्राहक है, और कस्टम, सार्थक अपवाद है कि कुछ एपीआई विशेष में urllib2 त्रुटियों लपेट शामिल है कि नहीं है। तो, मेरे पास यह एक पैटर्न है - कुछ तरीकों को पैच करना, और उनमें से एक पर साइड इफेक्ट्स सेट करना। मैं इसे शायद एक दर्जन अलग-अलग परीक्षणों में उपयोग करता हूं, और केवल अंतर तीन चर होते हैं जिनका उपयोग साइड_फैक्ट के हिस्से में किया जाता है, और MyClass() की विधि जिसे मैं कॉल करता हूं।

क्या यह एक सबसे तेज़ स्थिरता बनाने और इन चरों में पारित करने का कोई तरीका है?

उत्तर

15

आप अप्रत्यक्ष स्थिरता parametrization http://pytest.org/latest/example/parametrize.html#deferring-the-setup-of-parametrized-resources

@pytest.fixture() 
def your_fixture(request): 
    httpcode, message, url = request.param 
    mock_req = mock.MagicMock(spec_set=urllib2.Request) 
    with mock.patch('package.module.urllib2.urlopen', autospec=True) as mock_urlopen, \ 
     mock.patch('package.module.urllib2.Request', autospec=True) as mock_request: 
     mock_request.return_value = mock_req 
     mock_urlopen.side_effect = urllib2.HTTPError(url, httpcode, message, {}, None) 
     connection = MyClass() 
     with pytest.raises(MyException): 
      connection.some_function() # this changes 


@pytest.mark.parametrize('your_fixture', [ 
    (403, 'some message', 'some url') 
], indirect=True) 
def test(your_fixture): 
    ... 

उपयोग कर सकते हैं और your_fixture परीक्षण से पहले वांछित पैरामीटर

+0

मैंने विशेष रूप से कहा कि यह वही नहीं है जो मैं चाहता हूं ... मैं नहीं चाहता कि स्थिरता कई बार बनाई जाए, मैं बस इसमें पैरामीटर पास करना चाहता हूं। –

+1

मेरे कोड स्थिरता में केवल एक बार परीक्षण में चलाता है। वास्तव में मेरा कोड आपके जैसा ही करता है। अंतर जिस तरह से पैरामीटर पारित किया जाता है। यदि आप परीक्षण के अंदर पैरामीटर उत्पन्न करना चाहते हैं और फिर उन्हें स्थिरता में पास करना चाहते हैं - आपका कोड ऐसा करने का एकमात्र तरीका है। यदि पैरामीटर परीक्षण में पूर्वनिर्धारित हैं, तो मेरा कोड –

+0

ठीक है, ठीक है। –

6

मैं अपने प्रश्न पोस्ट करने के बाद से इस पर एक गुच्छा अधिक शोध किया है के साथ चलेंगे, और सबसे अच्छा मैं इसके साथ आ सकता हूं:

फिक्स्चर इस तरह से काम नहीं करते हैं। बस एक नियमित रूप से समारोह, यानी उपयोग करें:

def my_fixture(httpcode, message, url): 
    mock_req = mock.MagicMock(spec_set=urllib2.Request) 
    with mock.patch('package.module.urllib2.urlopen', autospec=True) as mock_urlopen, \ 
     mock.patch('package.module.urllib2.Request', autospec=True) as mock_request: 
     mock_request.return_value = mock_req 
     mock_urlopen.side_effect = urllib2.HTTPError(url, httpcode, message, {}, None) 
     connection = MyClass() 
     return (connection, mock_request, mock_urlopen) 

def test_something(): 
    connection, mock_req, mock_urlopen = my_fixture(401, 'some message', 'some url') 
    with pytest.raises(MyException): 
     connection.some_function() # this changes 
1

मैं जानता हूँ कि यह पुराना है, लेकिन शायद यह तो किसी को फिर से

@pytest.fixture 
def data_patcher(request): 

    def get_output_test_data(filename, as_of_date=None): 
     # a bunch of stuff to configure output 
     return output 

    def teardown(): 
     pass 

    request.addfinalizer(teardown) 

    return get_output_test_data 

और जो इस पर ठोकर मदद करता है, समारोह के अंदर:

with patch('function to patch', new=data_patcher): 
संबंधित मुद्दे

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