2015-02-04 10 views
6

वर्तमान में मेरे पास कई समानतम टेस्टकेस हैं। प्रत्येक टेस्टकेस में डेटा (इनपुट मान + अपेक्षित आउटपुट मान) और तर्क शामिल होते हैं (एसयूटी को कॉल करें और अपेक्षित आउटपुट के साथ वास्तविक आउटपुट की तुलना करें)।विरासत

मैं तर्क से डेटा को अलग करना चाहता हूं। इस प्रकार मैं एक बेस क्लास चाहता हूं जिसमें केवल तर्क और व्युत्पन्न कक्षा हो जिसमें केवल डेटा शामिल हो। मैं अब तक इस के साथ आया था:

import unittest 

class MyClass(): 
    def __init__(self, input): 
     self.input = input 
    def get_result(self): 
     return self.input * 2 

class TestBase(unittest.TestCase): 
    def check(self, input, expected_output): 
     obj = self.class_under_test(input) 
     actual_output = obj.get_result() 
     self.assertEqual(actual_output, expected_output) 

    def test_get_result(self): 
     for value in self.values: 
      self.check(value[0], value[1]) 

class TestMyClass(TestBase): 
    def __init__(self, methodName='runTest'): 
     unittest.TestCase.__init__(self, methodName)   
     self.class_under_test = MyClass 
     self.values = [(1, 2), (3, 6)] 

unittest.main(exit = False) 

लेकिन यह निम्न त्रुटि के साथ विफल:

AttributeError: 'TestBase' object has no attribute 'values' 

दो सवाल:

  • मेरी 'डिजाइन' किसी भी अच्छा है?
  • इसे काम करने के लिए अभी भी क्या आवश्यक है?
+0

ध्यान दें कि यह असामान्य है (मेरे अनुभव) किसी भी चीज़ के लिए 'टेस्टकेस .__ init__' का उपयोग करने के लिए। आम तौर पर, प्रारंभिक कोड 'TestCase.setUp' में जाता है। – mgilson

उत्तर

3

डिजाइन (कम या ज्यादा) है ठीक - एक "हिचकी" है कि unittest बिल्कुल testcase कक्षाएं लग रहा है और तरीकों कि उन पर "परीक्षण" के साथ शुरू चलता है जब। इस बिंदु पर आपके पास कुछ विकल्प हैं।

एक दृष्टिकोण परीक्षण और मूल्यों के तहत कक्षा को कक्षा पर विशेषताओं के रूप में निर्दिष्ट करना होगा। इधर, यदि संभव हो तो, आप मूल्यों अपरिवर्तनीय हो चाहता हूँ ...

class TestBase(unittest.TestCase): 

    def check(self, input, expected_output): 
     obj = self.class_under_test(input) 
     actual_output = obj.get_result() 
     self.assertEqual(actual_output, expected_output) 

    def check_all(self): 
     for value in self.values: 
      self.check(value[0], value[1]) 

class TestMyClass1(TestBase): 
    values = ((1, 2), (3, 4)) 
    class_under_test = MyClass1 

    def test_it(self): 
     self.check_all() 

class TestMyClass2(TestBase): 
    values = (('a', 'b'), ('d', 'e')) 
    class_under_test = MyClass2 

    def test_it(self): 
     self.check_all() 
4

यह काम करने के लिए उम्मीद के रूप में, आप न्यूनतम जरूरत के लिए:

  • सुनिश्चित करें कि आपके उपवर्गों की init विधि परीक्षण मामलों testcase से मेल, यानी __init__(self, methodName="runTest")
  • बनाओ एक सुपर कॉल जोड़ें init आपके उप-वर्गों की विधि उदा। super(TestMyClass, self).__init__(methodName)
  • test_get_result करने के लिए एक आत्म तर्क है, यानी def test_get_result(self):

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

+0

क्या आप मिश्रण के साथ बेहतर डिजाइन का उदाहरण दे सकते हैं? – compie

+0

इस उत्तर ने मुझे TestLoader()। LoadTestsFromModule() के साथ सामना की गई एक समान विरासत समस्या को हल करने में मदद की। संशोधित __init __() को जोड़ने के लिए मेरे लिए चाल थी। – killthrush

2

आप test_get_result() दो बार मार रहे हैं। मुझे नहीं लगता कि test*() विधियों को TestBase में होना चाहिए। इसके बजाय, TestBase का उपयोग कस्टम दावे, त्रुटि स्वरूपक, परीक्षण-डेटा जेनरेटर आदि प्रदान करने के लिए करें और TestMyClass में वास्तविक परीक्षण रखें।

0

पायथन के unittest.main() वर्तमान नाम स्थान में सभी परीक्षण वर्गों से सभी परीक्षणों निष्पादित करता है।

सीधे अपनी बेस क्लास में परीक्षण चलाने का एक तरीका यह है कि इसे किसी भिन्न मॉड्यूल (उदा।TestBasetestbase.py करने के लिए) के लिए कदम:

जो unittest.main() कॉल फ़ाइल में, अपने नाम स्थान में उस वर्ग आयात नहीं करना सुनिश्चित करें (from testbase import * उपयोग नहीं करते या समान): में

import testbase 

class TestMyClass1(testbase.TestBase): 
    values = ((1, 2), (3, 4)) 
    class_under_test = MyClass1 
संबंधित मुद्दे