AssertEqual und iterables von Unittest - überprüfen Sie nur den Inhalt

68

Gibt es eine "anständige" Möglichkeit, die Gleichheit des Inhalts von zwei iterierbaren Objekten zu überprüfen? Ich verwende viele Tupel, Listen und Numpy-Arrays und möchte normalerweise nur den Inhalt und nicht den Typ testen. Momentan gieße ich einfach den Typ:

self.assertEqual (tuple (self.numpy_data), tuple (self.reference_list))

Ich habe dieses Listenverständnis vor einiger Zeit verwendet:

[self.assertEqual (*x) for x in zip(self.numpy_data, self.reference_list)]

Diese Lösung scheint dem Typecast jedoch etwas unterlegen zu sein, da sie nur dann einzelne Werte druckt, wenn sie fehlschlägt, und auch nicht für unterschiedliche Referenz- und Datenlängen (aufgrund der Zip-Funktion) fehlschlägt.

Lucas Hoepner
quelle

Antworten:

99

Python 3

Python> = 2.7

Cédric Julien
quelle
Dies wird nicht das tun, was das OP angefordert hat, da die Reihenfolge der Elemente nicht berücksichtigt wird.
Sven Marnach
1
@Sven Marnach: Richtig, ich habe die assertSequenceEqual hinzugefügt, die nicht auftragsfrei ist
Cédric Julien
2
Leichte Klarstellung: 2.7 hat die gewünschte Funktionalität, also haben Sie wohl> = 2.7 statt> 2.7 gemeint. Auch sind diese Funktionen in 2,4-2,6 über die verfügbaren unittest2 Paket.
Mu Mind
4
Beachten Sie auch, dass assertSequenceEqualGeneratoren nicht verglichen werden können, da es den Anschein hat, als würden Sie versuchen, len()das Ergebnis abzurufen.
Dan Passaro
12
Ich habe versucht assertSequenceEqual, zwei numpyArrays zu vergleichen . Der Test gibt jedoch einen Wertefehler zurück, der besagt, dass "(...) der Wahrheitswert eines Arrays mit mehr als einem Element nicht eindeutig ist". Wenn A = numpy.array([0, 1, 2, 3, 4, 5])und ausgeführt wird B = numpy.array([0, 1, 2, 3, 4, 5]), wird self.assertSequenceEqual(A, B)der Fehler ausgelöst. Aber wenn ich self.assertSequenceEqual(list(A), list(B))die Testdurchläufe wie erwartet benutze . Ich möchte nur wissen, ob dies die richtige Art ist, den Test durchzuführen.
Regeirk
9

Sie können Ihrer TestCase-Klasse jederzeit Ihre eigenen Assertionsmethoden hinzufügen:

def assertSequenceEqual(self, it1, it2):
    self.assertEqual(tuple(it1), tuple(it2))

oder sehen Sie sich an, wie 2.7 es definiert hat: http://hg.python.org/cpython/file/14cafb8d1480/Lib/unittest/case.py#l621

Ned Batchelder
quelle
Die Definition im verknüpften Code unterscheidet sich von Ihrer Implementierung: Sie vergleicht sich mit Unterschieden in der Reihenfolge der Elemente.
Sven Marnach
Ups: assertItemsEqualist ungeordnet. Ich habe es behoben, um auf ein passenderes Beispiel hinzuweisen.
Ned Batchelder
assertItemsEqual verwendet außerdem die Datei collection.Counter, die den Hash der Objekte in der Sequenz verwendet. Bei Sequenzen von vom Benutzer erstellten Objekten ohne eine bestimmte Hash-Implementierung schlägt assertItemsEqual immer fehl (da der Hash auf der Objekt-ID basiert), selbst wenn die Objekte gleich sind (dh == ist wahr).
Tony Suffolk 66
0

Mir scheint, Sie interessieren sich für die Reihenfolge der Elemente in den Sequenzen. Deshalb ist assertItemsEqual/ assertCountEqualnichts für dich.

In Python 2.7 und in Python 3 möchten Sie Folgendes self.assertSequenceEqual. Dies hängt von der Reihenfolge der Artikel ab.

user7610
quelle