Ich versuche, einen automatisierten Test einer Anwendung zu schreiben, der im Grunde ein benutzerdefiniertes Nachrichtenformat in eine XML-Nachricht übersetzt und am anderen Ende sendet. Ich habe einen guten Satz von Eingabe / Ausgabe-Nachrichtenpaaren, daher muss ich nur die Eingabe-Nachrichten einschicken und darauf warten, dass die XML-Nachricht am anderen Ende herauskommt.
Wenn es darum geht, die tatsächliche Ausgabe mit der erwarteten Ausgabe zu vergleichen, treten einige Probleme auf. Mein erster Gedanke war nur, Zeichenfolgenvergleiche für die erwarteten und tatsächlichen Nachrichten durchzuführen. Dies funktioniert nicht sehr gut, da die Beispieldaten, die wir haben, nicht immer konsistent formatiert sind und häufig unterschiedliche Aliase für den XML-Namespace verwendet werden (und manchmal Namespaces überhaupt nicht verwendet werden).
Ich weiß, dass ich beide Zeichenfolgen analysieren und dann durch jedes Element gehen und sie selbst vergleichen kann. Dies wäre nicht allzu schwierig, aber ich habe das Gefühl, dass es einen besseren Weg oder eine Bibliothek gibt, die ich nutzen könnte.
Die Frage lautet also: Auf den Punkt gebracht:
Wie würden Sie bei zwei Java-Strings, die beide gültiges XML enthalten, feststellen, ob sie semantisch äquivalent sind? Bonuspunkte, wenn Sie die Unterschiede feststellen können.
Im Folgenden wird anhand von Standard-JDK-Bibliotheken überprüft, ob die Dokumente gleich sind.
normalize () ist da, um sicherzustellen, dass es keine Zyklen gibt (technisch würde es keine geben)
Für den obigen Code müssen die Leerzeichen innerhalb der Elemente jedoch identisch sein, da sie beibehalten und ausgewertet werden. Der mit Java
xml:space
gelieferte Standard-XML-Parser ermöglicht es Ihnen nicht, eine Funktion für die Bereitstellung einer kanonischen Version festzulegen oder zu verstehen, ob dies ein Problem darstellt. Möglicherweise benötigen Sie einen XML-Ersatzparser wie xerces oder verwenden JDOM.quelle
setIgnoringElementContentWhitespace(false)
Xom verfügt über ein Canonicalizer-Dienstprogramm, das Ihre DOMs in eine reguläre Form umwandelt, die Sie dann anordnen und vergleichen können. Unabhängig von Leerzeichenunregelmäßigkeiten oder Attributreihenfolgen können Sie regelmäßige, vorhersehbare Vergleiche Ihrer Dokumente erhalten.
Dies funktioniert besonders gut in IDEs mit dedizierten visuellen String-Komparatoren wie Eclipse. Sie erhalten eine visuelle Darstellung der semantischen Unterschiede zwischen den Dokumenten.
quelle
Die neueste Version von XMLUnit kann dazu beitragen, dass zwei XML- Dateien gleich sind. Auch
XMLUnit.setIgnoreWhitespace()
undXMLUnit.setIgnoreAttributeOrder()
kann für den fraglichen Fall notwendig sein.Siehe Arbeitscode eines einfachen Beispiels für die Verwendung von XML-Einheiten weiter unten.
Wenn Sie Maven verwenden, fügen Sie Folgendes hinzu
pom.xml
:quelle
Danke, ich habe das erweitert, versuche das ...
quelle
Aufbauend auf Toms Antwort finden Sie hier ein Beispiel mit XMLUnit v2.
Es verwendet diese Maven-Abhängigkeiten
..und hier ist der Testcode
Die Dokumentation, in der dies beschrieben wird, lautet https://github.com/xmlunit/xmlunit#comparing-two-documents
quelle
Skaffman scheint eine gute Antwort zu geben.
Eine andere Möglichkeit besteht wahrscheinlich darin, das XML mit einem Befehlszeilenprogramm wie xmlstarlet ( http://xmlstar.sourceforge.net/ ) zu formatieren und dann beide Zeichenfolgen zu formatieren und dann ein beliebiges diff-Dienstprogramm (Bibliothek) zu verwenden, um die resultierenden Ausgabedateien zu unterscheiden. Ich weiß nicht, ob dies eine gute Lösung ist, wenn Probleme mit Namespaces auftreten.
quelle
AssertJ 1.4+ enthält spezielle Zusicherungen zum Vergleichen von XML-Inhalten:
Hier ist die Dokumentation
quelle
Ich verwende Altova DiffDog, das Optionen zum strukturellen Vergleichen von XML-Dateien bietet (ohne Berücksichtigung von Zeichenfolgendaten).
Dies bedeutet, dass (wenn Sie die Option "Text ignorieren" aktivieren):
und
sind gleich in dem Sinne, dass sie strukturelle Gleichheit haben. Dies ist praktisch, wenn Sie Beispieldateien haben, die sich in den Daten unterscheiden, aber nicht strukturiert sind!
quelle
Dadurch werden XMLs mit vollständigen Zeichenfolgen verglichen (unterwegs neu formatiert). Es macht es einfach, mit Ihrer IDE (IntelliJ, Eclipse) zu arbeiten, da Sie einfach klicken und den Unterschied in den XML-Dateien visuell sehen.
Ich bevorzuge dies gegenüber XmlUnit, da der Client-Code (Testcode) sauberer ist.
quelle
Der folgende Code funktioniert für mich
quelle
Verwenden von JExamXML mit einer Java-Anwendung
quelle
Ich benötigte die gleiche Funktionalität wie in der Hauptfrage angefordert. Da ich keine Bibliotheken von Drittanbietern verwenden durfte, habe ich meine eigene Lösung basierend auf der @ Archimedes Trajano-Lösung erstellt.
Das Folgende ist meine Lösung.
Es vergleicht zwei XML-Zeichenfolgen und behebt alle nicht übereinstimmenden Namespace-Zuordnungen, indem sie in eindeutige Werte in beiden Eingabezeichenfolgen übersetzt werden.
Kann fein abgestimmt werden, dh bei Übersetzung von Namespaces. Aber für meine Anforderungen macht es einfach den Job.
quelle
Da Sie "semantisch äquivalent" sagen, meine ich, dass Sie mehr als nur buchstäblich überprüfen möchten, ob die XML-Ausgaben (Zeichenfolge) gleich sind und ob Sie so etwas möchten
<foo> ein paar Sachen hier </ foo> </ code>
und
<foo> ein paar Sachen hier </ foo> </ code>
Lesen Sie als gleichwertig. Letztendlich wird es wichtig sein, wie Sie "semantisch äquivalent" für jedes Objekt definieren, von dem Sie die Nachricht wiederherstellen. Erstellen Sie dieses Objekt einfach aus den Nachrichten und definieren Sie mit einem benutzerdefinierten equals (), wonach Sie suchen.
quelle