2010-10-08 9 views
32

मेरे पास पाइथन में निम्न कार्य है और मैं अनजान के साथ परीक्षण करना चाहता हूं कि अगर कार्य 0 तर्क के रूप में मिलता है, तो यह चेतावनी फेंकता है। मैंने पहले ही assertRaises की कोशिश की है, लेकिन चूंकि मैं चेतावनी नहीं उठाता, यह काम नहीं करता है।पायथन के अनजान के साथ परीक्षण कैसे करें कि एक चेतावनी फेंक दी गई है?

def isZero(i): 
     if i != 0: 
     print "OK" 
     else: 
     warning = Warning("the input is 0!") 
     print warning 
     return i 

धन्यवाद, टॉमस

+0

* के आसपास काम करने के संबंध में ... यदि एक चेतावनी पहले से ही एक बार/डिफ़ॉल्ट नियम के कारण उठाई गई है, तो कोई फर्क नहीं पड़ता कि चेतावनी सेट करने वाले फ़िल्टर को तब तक नहीं देखा जाएगा जब चेतावनी रजिस्ट्री चेतावनी से संबंधित न हो साफ़ कर दिया गया है। * ([डॉक्स] (https://docs.python.org/3/library/warnings.html#testing- चेतावनी)) [इस आलेख] देखें (https://blog.ionelmc.ro/2013/06/26/परीक्षण-पायथन-चेतावनियां /) मॉड्यूल स्तर '__warningregistry__' (रजिस्ट्री दस्तावेज़ का उल्लेख) के बारे में। – saaj

उत्तर

30

आप catch_warnings संदर्भ प्रबंधक का उपयोग कर सकते हैं। अनिवार्य रूप से यह आपको चेतावनियों हैंडलर का नकल करने की अनुमति देता है, ताकि आप चेतावनी के विवरण को सत्यापित कर सकें। एक पूर्ण स्पष्टीकरण और नमूना परीक्षण कोड के लिए official docs देखें।

import warnings 

def fxn(): 
    warnings.warn("deprecated", DeprecationWarning) 

with warnings.catch_warnings(record=True) as w: 
    # Cause all warnings to always be triggered. 
    warnings.simplefilter("always") 
    # Trigger a warning. 
    fxn() 
    # Verify some things 
    assert len(w) == 1 
    assert issubclass(w[-1].category, DeprecationWarning) 
    assert "deprecated" in str(w[-1].message) 
+0

+1। निफ्टी और उपयोगी। –

+0

ध्यान दें कि यह थ्रेड सुरक्षित नहीं है, क्योंकि यह 'वैश्विक स्थिति' को संशोधित करता है - यदि आप इसे परीक्षण सूट में उपयोग करते हैं और अन्य चेतावनियां उत्सर्जित होती हैं, तो ये 'catch_warnings' में भी दिखाई देगी, जो झूठी नकारात्मकताओं का कारण बन सकती है। – nlsdfnbch

4

@ire_and_curses 'answer काफी उपयोगी विहित है और मुझे लगता है कि। एक ही काम करने का एक और तरीका है। इसके लिए माइकल फॉर्ड के उत्कृष्ट Mock library की आवश्यकता है।

import unittest, warnings 
from mock import patch_object 

def isZero(i): 
    if i != 0: 
    print "OK" 
    else: 
    warnings.warn("the input is 0!") 
    return i 

class Foo(unittest.TestCase): 
    @patch_object(warnings, 'warn') 
    def test_is_zero_raises_warning(self, mock_warn): 
     isZero(0) 
     self.assertTrue(mock_warn.called) 

if __name__ == '__main__': 
    unittest.main() 

गंधा patch_object आप warn विधि बाहर नकली सुविधा देता है।

+0

अच्छा समाधान .. – pelson

+0

+1 - यह समाधान स्वीकृत उत्तर से बेहतर है, क्योंकि यह 'चेतावनियों' लाइब्रेरी की वैश्विक स्थिति का उपयोग नहीं करता है - जो झूठी नकारात्मकताओं का कारण बन सकता है। – nlsdfnbch

17

आप पकड़-चेतावनी संदर्भ को अपनाने के लिए अपना स्वयं का जोर चेतावनी कार्य लिख सकते हैं। मैं सिर्फ यह नीचे दिए तरीक़े को क्रियान्वित किया है, एक mixin साथ:

class WarningTestMixin(object): 
    'A test which checks if the specified warning was raised' 

    def assertWarns(self, warning, callable, *args, **kwds): 
     with warnings.catch_warnings(record=True) as warning_list: 
      warnings.simplefilter('always') 

      result = callable(*args, **kwds) 

      self.assertTrue(any(item.category == warning for item in warning_list)) 

एक के उपयोग का उदाहरण:

class SomeTest(WarningTestMixin, TestCase): 
    'Your testcase' 

    def test_something(self): 
     self.assertWarns(
      UserWarning, 
      your_function_which_issues_a_warning, 
      5, 10, 'john', # args 
      foo='bar'  # kwargs 
     ) 

परीक्षा उत्तीर्ण होगा अगर your_function द्वारा जारी चेतावनी के कम से कम एक प्रकार UserWarning की है ।

+0

यह उत्तर worksassertRaisesRegexp (UserWarning, # 'इनपुट फ़ाइल एक पीडीएफ नहीं है: केवल tika', # metac.apply, # self.notpdf) – alemol

+0

यह उत्तर काम करता है। हालांकि [प्रलेखन] (https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaisesRegexp) कहता है कि "यह भी जांचना संभव है कि अपवाद और चेतावनियां निम्न विधियों का उपयोग करके उठाई गई हैं: assertRaises (अपवाद, कॉल करने योग्य, * args, ** kwds), assertRaises (अपवाद) " तो मैंने 'assertRaisesRegexp (उपयोगकर्ता चेतावनी,' मेरा युद्ध संदेश ', function_which_issues_a_warning, args) की कोशिश की, लेकिन मेरा परीक्षण विफल: AssertionError: UserWarning नहीं उठाया गया । क्या कोई उदाहरण पोस्ट कर सकता है? – alemol

+0

शायद यह खराब दस्तावेज़ है ... शायद यह काम करता है यदि आप उपयोगकर्ता चेतावनी बढ़ाते हैं, लेकिन आपको चेतावनियां उठाना नहीं है, तो आपको 'चेतावनियां' माना जाता है।चेतावनी() 'उन्हें, इसलिए एक अलग पकड़ की जरूरत है – Anentropic

11

पायथन 3.2 से शुरू, आप बस assertWarns() विधि का उपयोग कर सकते हैं।

with self.assertWarns(Warning): 
    do_something() 
संबंधित मुद्दे