Próbuję napisać automatyczny test aplikacji, który w zasadzie tłumaczy niestandardowy format wiadomości na komunikat XML i wysyła go na drugi koniec. Mam dobry zestaw par komunikatów wejściowych / wyjściowych, więc wszystko, co muszę zrobić, to wysłać wiadomości wejściowe i nasłuchiwać wiadomości XML wychodzącej z drugiego końca.
Kiedy przychodzi czas na porównanie rzeczywistej mocy wyjściowej z oczekiwaną, mam problemy. Moją pierwszą myślą było po prostu porównanie ciągów oczekiwanych i rzeczywistych komunikatów. Nie działa to zbyt dobrze, ponieważ przykładowe dane, które mamy, nie zawsze są konsekwentnie formatowane i często zdarza się, że w przestrzeni nazw XML stosowane są różne aliasy (a czasami przestrzenie nazw wcale nie są używane).
Wiem, że mogę przeanalizować oba ciągi, a następnie przejść przez każdy element i porównać je osobiście, co nie byłoby zbyt trudne, ale mam wrażenie, że istnieje lepszy sposób lub biblioteka, którą mógłbym wykorzystać.
Sprowadzone pytanie brzmi:
Biorąc pod uwagę dwa ciągi Java, które zawierają poprawny kod XML, jak byś zajął się określaniem, czy są one semantycznie równoważne? Punkty bonusowe, jeśli potrafisz określić różnice.
Poniższe sprawdzi, czy dokumenty są równe przy użyciu standardowych bibliotek JDK.
normalize () jest po to, aby upewnić się, że nie ma cykli (technicznie nie byłoby żadnych)
Powyższy kod wymaga jednak, aby białe spacje były takie same w elementach, ponieważ zachowuje je i ocenia. Standardowy analizator XML dostarczany z Javą nie pozwala ustawić funkcji zapewniającej wersję kanoniczną ani zrozumieć,
xml:space
czy to będzie problem, wtedy może być potrzebny zastępczy analizator XML, taki jak xerces, lub użyj JDOM.źródło
setIgnoringElementContentWhitespace(false)
Xom ma narzędzie Canonicalizer, które zamienia DOM w zwykłą formę, którą można następnie skreślić i porównać. Niezależnie od nieprawidłowości białych znaków i kolejności atrybutów, możesz uzyskać regularne, przewidywalne porównania swoich dokumentów.
Działa to szczególnie dobrze w IDE, które mają dedykowane wizualne komparatory napisów, takie jak Eclipse. Otrzymasz wizualną reprezentację różnic semantycznych między dokumentami.
źródło
Najnowsza wersja XMLUnit może pomóc w zapewnieniu dwóch XML-ów. Również
XMLUnit.setIgnoreWhitespace()
iXMLUnit.setIgnoreAttributeOrder()
może być konieczne w danym przypadku.Zobacz działający kod prostego przykładu użycia Jednostki XML poniżej.
Jeśli używasz Maven, dodaj to do
pom.xml
:źródło
Dzięki, rozszerzyłem to, spróbuj tego ...
źródło
Opierając się na odpowiedzi Toma , oto przykład użycia XMLUnit v2.
Wykorzystuje te zależności od raju
..i oto kod testowy
Dokumentacja, która to określa, to https://github.com/xmlunit/xmlunit#comparing-two-documents
źródło
wydaje się, że skaffman daje dobrą odpowiedź.
innym sposobem jest prawdopodobnie sformatowanie XML za pomocą narzędzia linii poleceń, takiego jak xmlstarlet ( http://xmlstar.sourceforge.net/ ), a następnie sformatowanie obu ciągów, a następnie użycie dowolnego narzędzia (biblioteki) diff do różnicowania powstałych plików wyjściowych. Nie wiem, czy to dobre rozwiązanie, gdy występują problemy z przestrzeniami nazw.
źródło
AssertJ 1.4+ ma określone twierdzenia do porównywania treści XML:
Oto dokumentacja
źródło
Używam Altova DiffDog, który ma opcje strukturalnego porównywania plików XML (ignorowanie danych ciągu).
Oznacza to, że (jeśli zaznaczysz opcję „zignoruj tekst”):
i
są równi w tym sensie, że mają równość strukturalną. Jest to przydatne, jeśli masz przykładowe pliki, które różnią się danymi, ale nie mają struktury!
źródło
Spowoduje to porównanie pełnych ciągów plików XML (ich formatowanie po drodze). Ułatwia pracę z twoim IDE (IntelliJ, Eclipse), ponieważ wystarczy kliknąć i zobaczyć różnicę w plikach XML.
Wolę to niż XmlUnit, ponieważ kod klienta (kod testowy) jest czystszy.
źródło
Poniższy kod działa dla mnie
źródło
Używanie JExamXML z aplikacją Java
źródło
Wymagałem takiej samej funkcjonalności, jak wymagana w pytaniu głównym. Ponieważ nie mogłem korzystać z żadnych bibliotek stron trzecich, stworzyłem własne rozwiązanie w oparciu o rozwiązanie @Archimedes Trajano.
Oto moje rozwiązanie.
Porównuje dwa ciągi XML i dba o wszelkie niedopasowane odwzorowania przestrzeni nazw, tłumacząc je na unikalne wartości w obu ciągach wejściowych.
Można go dostroić, np. W przypadku tłumaczenia przestrzeni nazw. Ale według moich wymagań po prostu działa.
źródło
Ponieważ mówisz „semantycznie równoważny”, zakładam, że masz na myśli, że chcesz zrobić coś więcej niż po prostu dosłownie sprawdzić, czy dane wyjściowe xml są (ciąg) równe i że chcesz czegoś takiego
<foo> kilka rzeczy tutaj </foo> </code>
i
<foo> kilka rzeczy tutaj </foo> </code>
czytaj jako równoważne. Ostatecznie będzie miało znaczenie, w jaki sposób definiujesz „semantycznie równoważny” dla dowolnego obiektu, z którego odtwarzana jest wiadomość. Po prostu zbuduj ten obiekt z wiadomości i użyj niestandardowego znaku równości (), aby zdefiniować to, czego szukasz.
źródło