2013-08-27 11 views
17

पर लागू किया गया है, मुझे पता है कि, पर एक शब्दकोश पर, assertDictEqual कहा जाता है। इसी प्रकार, अनुक्रम पर assertEqualassertSequenceEqual प्रदर्शन करेगा।assertDictEqual के साथ assertDequEqual को प्राप्त करने के लिए मूल्य

हालांकि, जब assertDictEqual मानों की तुलना की है, यह assertEqual का उपयोग करना नहीं दिखाई देता है, और इस तरह assertSequenceEqual नहीं बुलाया जाता है।

lst1 = [1, 2] 
lst2 = [2, 1] 

d1 = {'key': lst1} 
d2 = {'key': lst2} 

self.assertEqual(lst1, lst2) # True 
self.assertEqual(d1, d2) # False >< 

मैं ऐसे d1 और d2 ऐसी है कि उनकी समानता ठीक से तुलना की जाती है के रूप में शब्दकोशों कैसे परीक्षण कर सकते हैं, रिकर्सिवली मूल्यों के assertEqual की तरह अर्थ विज्ञान लगाने से:

सरल निम्नलिखित शब्दकोशों पर विचार करें?

मैं बाहरी मॉड्यूल का उपयोग करना चाहता हूं (जैसा कि in this question सुझाया गया है) यदि संभव हो तो, जब तक कि वे देशी django एक्सटेंशन न हों।


संपादित

अनिवार्य रूप से, मैं क्या कर रहा हूँ के बाद एक इस के संस्करण में बनाया गया है:

def assertDictEqualUnorderedValues(self, d1, d2): 
    for k,v1 in d1.iteritems(): 
     if k not in d2: 
      self.fail('Key %s missing in %s'%(k, d2)) 

     v2 = d2[k] 

     if isinstance(v1, Collections.iterable) and not isinstance(v1, basestring): 
      self.assertValuesEqual(v1, v2) 
     else: 
      self.assertEqual(v1, v2) 

ऊपर कोड के साथ समस्या यह है कि त्रुटि संदेश के रूप में के रूप में अच्छा नहीं कर रहे हैं बिल्टिन आवेषण, और शायद किनारे के मामलों को मैंने अनदेखा कर दिया है (जैसा कि मैंने अभी लिखा है कि मेरे सिर के ऊपर से)।

+2

'unittest' मॉड्यूल के साथ, 'self.assertEqual (lst1, lst2)' सत्य नहीं है -> 'AssertionError: सूचियां अलग-अलग हैं: [1, 2]! = [2, 1]'। – martineau

+0

@ मार्टिनौ - मेरी गलती; मैं प्रलेखन के उस हिस्से को गलत तरीके से पढ़ता हूं। मैं 'assertSequemsEqual' – sapi

+1

की बजाय 'assertItemsEqual' के बराबर की तलाश में हूं, ठीक है, अगर आप' lst1' और 'lst2' बनाते हैं तो पहले' assertEqual' सफल होता है, तो दूसरा भी होगा। – martineau

उत्तर

4

TestCase.assertEqual() विधि वर्ग 'dicts के लिए assertDictEqual() कहता है, तो बस है कि आपके उपवर्ग व्युत्पत्ति में ओवरराइड। यदि आप विधि में केवल assertXXX विधियों का उपयोग करते हैं, तो त्रुटि संदेश अंतर्निहित आवेषण के रूप में लगभग उतना ही अच्छा होना चाहिए - लेकिन यदि आप नहीं देखते हैं तो आप msg कीवर्ड तर्क प्रदान कर सकते हैं जब आप उन्हें प्रदर्शित करने के लिए कॉल करते हैं।

import collections 
import unittest 

class TestSOquestion(unittest.TestCase): 

    def setUp(self): 
     pass # whatever... 

    def assertDictEqual(self, d1, d2, msg=None): # assertEqual uses for dicts 
     for k,v1 in d1.iteritems(): 
      self.assertIn(k, d2, msg) 
      v2 = d2[k] 
      if(isinstance(v1, collections.Iterable) and 
       not isinstance(v1, basestring)): 
       self.assertItemsEqual(v1, v2, msg) 
      else: 
       self.assertEqual(v1, v2, msg) 
     return True 

    def test_stuff(self): 
     lst1 = [1, 2] 
     lst2 = [2, 1] 

     d1 = {'key': lst1} 
     d2 = {'key': lst2} 

     self.assertItemsEqual(lst1, lst2) # True 
     self.assertEqual(d1, d2) # True 

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

आउटपुट:

> python unittest_test.py 
. 
----------------------------------------------------------------------> 
Ran 1 test in 0.000s 

OK 

> 
+1

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

+0

ठीक है, लेकिन मुझे अभी भी समझ में नहीं आता है कि आप अपने कोड में पहले 'assertEqual (lst1, lst2) 'को सही क्यों मानते हैं। – martineau

+0

यह समाधान गहरा घोंसला वाली डिक्ट्स + सूचियों पर काम नहीं करता है। सॉर्टिंग के आधार पर समाधान करता है। – Federico

7

बजाय assertDictEqual अधिभावी, क्यों नहीं आप रिकर्सिवली अपने dicts तरह पहले करते हैं?

def deep_sort(obj): 
    """ 
    Recursively sort list or dict nested lists 
    """ 

    if isinstance(obj, dict): 
     _sorted = {} 
     for key in sorted(obj): 
      _sorted[key] = deep_sort(obj[key]) 

    elif isinstance(obj, list): 
     new_list = [] 
     for val in obj: 
      new_list.append(deep_sort(val)) 
     _sorted = sorted(new_list) 

    else: 
     _sorted = obj 

    return _sorted 

फिर प्रकार है, और सामान्य assertDictEqual का उपयोग करें:

dict1 = deep_sort(dict1) 
    dict2 = deep_sort(dict2) 

    self.assertDictEqual(dict1, dict2) 

यह दृष्टिकोण के बारे में कितने स्तर नीचे अपनी सूची हैं देखभाल नहीं को लाभ मिलता है।

+2

'अपवाद:' <'' dict 'और' dict'' – tdc

1

मुझे एक ही समस्या थी, मुझे परीक्षण करना था कि मॉडल के क्षेत्र सही हैं या नहीं। और MyModel._meta.get_all_field_names() कभी-कभी ['a', 'b'] और कभी-कभी ['b', 'a'] लौटाता है।

जब मैं चलाएँ:

self.assertEqual(MyModel._meta.get_all_field_names(), ['a', 'b']) 

यह कभी कभी विफल रहता है।साथ

self.assertEqual(set(MyModel._meta.get_all_field_names()), set(['a', 'b'])) #true 

self.assertEqual(set(MyModel._meta.get_all_field_names()), set(['b', 'a'])) #true 

यह काम नहीं करेगा (ट्रू रिटर्न):

self.assertEqual(set(['a','a','b','a']), set(['a','b'])) # Also true 

लेकिन चूंकि मैं फ़ील्ड नामों के लिए जाँच कर रहा हूँ

मैं एक सेट() में दोनों मान रख कर इसे हल एक मॉडल के, और वे अद्वितीय हैं, यह मेरे द्वारा अच्छा है।

+0

के उदाहरणों के बीच समर्थित नहीं है 'आप सेट ([' '', 'b'] 'की बजाय' इसे सुधारने के लिए सेट नोटेशन का उपयोग कर सकते हैं ''' एक ',' ख '} '। साथ ही, एक समारोह 'self.assertSetEqual ({' a ',' a ',' b ',' a '}, {' a ',' b '}) है, जो दो सेटों के बीच अंतर की जांच करेगा और असफल हो अगर वे बिल्कुल वही तत्व नहीं रखते हैं। – Mouscellaneous

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