2011-03-03 7 views
12

की खोज नहीं यह unittest and metaclass: automatic test_* method generation के लिए एक अनुवर्ती सवाल यह है:नाक, unittest.TestCase और metaclass: स्वत: जनरेट test_ * तरीकों

इस (निर्धारित) unittest.TestCase लेआउट के लिए:

#!/usr/bin/env python 

import unittest 


class TestMaker(type): 

    def __new__(cls, name, bases, attrs): 
     callables = dict([ 
      (meth_name, meth) for (meth_name, meth) in attrs.items() if 
      meth_name.startswith('_test') 
     ]) 

     for meth_name, meth in callables.items(): 
      assert callable(meth) 
      _, _, testname = meth_name.partition('_test') 

      # inject methods: test{testname}_v4,6(self) 
      for suffix, arg in (('_false', False), ('_true', True)): 
       testable_name = 'test{0}{1}'.format(testname, suffix) 
       testable = lambda self, func=meth, arg=arg: func(self, arg) 
       attrs[testable_name] = testable 

     return type.__new__(cls, name, bases, attrs) 


class TestCase(unittest.TestCase): 

    __metaclass__ = TestMaker 

    def test_normal(self): 
     print 'Hello from ' + self.id() 

    def _test_this(self, arg): 
     print '[{0}] this: {1}'.format(self.id(), str(arg)) 

    def _test_that(self, arg): 
     print '[{0}] that: {1}'.format(self.id(), str(arg)) 


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

यह stdlib के ढांचे का उपयोग कर काम करता है। उम्मीद और वास्तविक उत्पादन:

C:\Users\santa4nt\Desktop>C:\Python27\python.exe test_meta.py 
Hello from __main__.TestCase.test_normal 
.[__main__.TestCase.test_that_false] that: False 
.[__main__.TestCase.test_that_true] that: True 
.[__main__.TestCase.test_this_false] this: False 
.[__main__.TestCase.test_this_true] this: True 
. 
---------------------------------------------------------------------- 
Ran 5 tests in 0.015s 

OK 

हालांकि, बाद से मैं वास्तव में nose उपयोग कर रहा हूँ, इस चाल इसके साथ सहमत नहीं हो रहा है। उत्पादन मुझे मिल गया है:

C:\Users\santa4nt\Desktop>C:\Python27\python.exe C:\Python27\Scripts\nosetests test_meta.py 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 

संक्षेप में, metaclass द्वारा उत्पन्न test_* तरीकों nose साथ रजिस्टर नहीं है। क्या कोई इस पर प्रकाश डाल सकता है?

धन्यवाद,

+0

http://ivory.idyll.org/articles/nose-intro.html#a-somewhat- पर एक नज़र डालें अधिक-पूरा-गाइड करने के लिए परीक्षण की खोज और निष्पादन। '-vv' के साथ चलने से आपको वह जानकारी मिल सकती है जो आपको चाहिए। – ncoghlan

+0

http://stackoverflow.com/questions/347574/how-do-i-get-nose-to-discover- गतिशील- जनरेटेड- टेस्टकेसेस – ncoghlan

+0

पर भी देखें, ठीक है, आप क्या जानते हैं, कोई ऐसा कुछ करने की कोशिश कर रहा था । मैंने नाक के परीक्षण जनरेटर को देखा है, लेकिन दुर्भाग्य से यह 'unittest.TestCase' से व्युत्पन्न परीक्षण कक्षाओं का समर्थन नहीं करता है और मुझे इसके उप-वर्ग पेड़ों में परिभाषित फिक्स्चर की आवश्यकता है। – Santa

उत्तर

17

तो, दोनों stdlib के unittest और नाक के लोडर और चयनकर्ता स्रोत कोड के माध्यम से sleuthing के बाद, यह पता चला है कि नाक को ओवरराइड करता है unittest.TestLoader.getTestCaseNames अपनी ही चयनकर्ता (प्लगइन अंकों के साथ) का उपयोग करें।

अब, नाक का चयनकर्ता कुछ regexes, काले और सफेद सूचियों, और प्लगइन्स के निर्णयों से मेल खाने के लिए संभावित विधि method.__name__ की तलाश करता है।

मेरे मामले में, गतिशील रूप से जेनरेट किए गए कार्यों में testable.__name__ == '<lambda>' है, जो नाक के चयनकर्ता मानदंडों से मेल नहीं खाता है।

ठीक करने के लिए,

 # inject methods: test{testname}_v4,6(self) 
     for suffix, arg in (('_false', False), ('_true', True)): 
      testable_name = 'test{0}{1}'.format(testname, suffix) 
      testable = lambda self, arg=arg: meth(self, arg) 
      testable.__name__ = testable_name # XXX: the fix 
      attrs[testable_name] = testable 

और यकीन है कि पर्याप्त:

(sandbox-2.7)bash-3.2$ nosetests -vv 
test_normal (test_testgen.TestCase) ... ok 
test_that_false (test_testgen.TestCase) ... ok 
test_that_true (test_testgen.TestCase) ... ok 
test_this_false (test_testgen.TestCase) ... ok 
test_this_true (test_testgen.TestCase) ... ok 

---------------------------------------------------------------------- 
Ran 5 tests in 0.005s 

OK