2016-03-18 14 views
3

Gibt es eine Möglichkeit verschachtelte Datenstrukturen in unittest zu vergleichen, sondern konkrete Typen von Objekten, wie assertSequenceEqual aber rekursive ignoriert, zum Beispiel:Python: Vergleich verschachtelte Datenstrukturen in Unittest

#!/usr/bin/env python 

import unittest 

class DeepCompareTestCase(unittest.TestCase): 

    def test_compare(self): 
     # this test fails 
     self.assertSequenceEqual(
      [['abc', 'def']], 
      (('abc', 'def'),) 
     ) 

unittest.main() 

(so etwas wie Test::Deep in Perl)

Antwort

1

Würde so etwas funktionieren?

import unittest 
from itertools import zip_longest 

class RecursiveTestCase(unittest.TestCase): 
    def assertSequenceDeepEqual(self, x, y): 
     MissingValue = MissingValueSentinel() 
     for x, y, in zip_longest(x, y, fillvalue=MissingValue): 
      try: 
       self.assertSequenceDeepEqual(self, x, y) 
      except TypeError: 
       self.assertEqual(x, y) 

       self.assertIsNot(x, MissingValue) 
       self.assertIsNot(y, MissingValue) 

class MissingValueSentinel(object): 
    pass 

zip_longest wirft TypeError wenn eine oder mehrere der Elemente ist kein Iterator, was darauf hindeutet Sie am unteren Rand der Rekursion sind.

Wenn einer der Iteratoren kürzer ist als der andere, gebe ich ein benutzerdefiniertes MissingValueSentinel Objekt zurück, das durch die assertIsNot Aufrufe am Ende der Funktion erkannt wird. Der einzige Grund dafür wäre, wenn x oder y eine Klasse hat, die aus irgendeinem Grund gleich Ad-hoc-Klassen wie MissingValueSentinel vergleicht, aber assertEqual noch immer zwischen zwei verschiedenen Objekten dieser Klasse sinnvoll ist. Das scheint ein ziemlich seltsamer Randfall zu sein und Sie können ihn wahrscheinlich ignorieren.

Die Verwendung von zip_longest anstelle von zip verhindert, dass [1, 2, 3] nicht richtig übereinstimmt [1, 2].