Estoy tratando de escribir una prueba automatizada de una aplicación que básicamente traduce un formato de mensaje personalizado en un mensaje XML y lo envía al otro extremo. Tengo un buen conjunto de pares de mensajes de entrada / salida, por lo que todo lo que necesito hacer es enviar los mensajes de entrada y escuchar el mensaje XML que sale por el otro extremo.
Cuando llega el momento de comparar la salida real con la salida esperada, me encuentro con algunos problemas. Mi primer pensamiento fue hacer comparaciones de cadenas en los mensajes esperados y reales. Esto no funciona muy bien porque los datos de ejemplo que tenemos no siempre están formateados de manera consistente y a menudo se usan diferentes alias para el espacio de nombres XML (y a veces los espacios de nombres no se usan en absoluto).
Sé que puedo analizar ambas cadenas y luego recorrer cada elemento y compararlas yo mismo y esto no sería demasiado difícil de hacer, pero tengo la sensación de que hay una mejor manera o una biblioteca que podría aprovechar.
Entonces, resumido, la pregunta es:
Dadas dos cadenas de Java que contienen XML válido, ¿cómo determinaría si son semánticamente equivalentes? Puntos de bonificación si tiene una manera de determinar cuáles son las diferencias.
Lo siguiente verificará si los documentos son iguales utilizando las bibliotecas JDK estándar.
normalize () está ahí para asegurarse de que no haya ciclos (técnicamente no habría ninguno)
Sin embargo, el código anterior requerirá que los espacios en blanco sean los mismos dentro de los elementos, porque lo conserva y evalúa. El analizador XML estándar que viene con Java no le permite configurar una función para proporcionar una versión canónica o comprender
xml:space
si eso va a ser un problema, entonces es posible que necesite un analizador XML de reemplazo como xerces o usar JDOM.fuente
setIgnoringElementContentWhitespace(false)
Xom tiene una utilidad Canonicalizer que convierte sus DOM en una forma regular, que luego puede clasificar en cadena y comparar. Por lo tanto, independientemente de las irregularidades del espacio en blanco o el orden de los atributos, puede obtener comparaciones regulares y predecibles de sus documentos.
Esto funciona especialmente bien en IDE que tienen comparadores de cadenas visuales dedicados, como Eclipse. Obtiene una representación visual de las diferencias semánticas entre los documentos.
fuente
La última versión de XMLUnit puede ayudar a afirmar que dos XML son iguales. También
XMLUnit.setIgnoreWhitespace()
yXMLUnit.setIgnoreAttributeOrder()
puede ser necesario para el caso en cuestión.Vea el código de trabajo de un ejemplo simple de uso de la Unidad XML a continuación.
Si usa Maven, agregue esto a su
pom.xml
:fuente
Gracias, extendí esto, prueba esto ...
fuente
Sobre la base de la respuesta de Tom , aquí hay un ejemplo usando XMLUnit v2.
Utiliza estas dependencias de Maven
..y aquí está el código de prueba
La documentación que describe esto es https://github.com/xmlunit/xmlunit#comparing-two-documents
fuente
skaffman parece estar dando una buena respuesta.
Otra forma es probablemente formatear el XML utilizando una utilidad de línea de comando como xmlstarlet ( http://xmlstar.sourceforge.net/ ) y luego formatear ambas cadenas y luego usar cualquier utilidad diff (biblioteca) para diferenciar los archivos de salida resultantes. No sé si esta es una buena solución cuando hay problemas con los espacios de nombres.
fuente
AssertJ 1.4+ tiene aserciones específicas para comparar contenido XML:
Aquí está la documentación
fuente
Estoy usando Altova DiffDog que tiene opciones para comparar archivos XML estructuralmente (ignorando los datos de cadena).
Esto significa que (si marca la opción 'ignorar texto'):
y
son iguales en el sentido de que tienen igualdad estructural. ¡Esto es útil si tiene archivos de ejemplo que difieren en datos, pero no en estructura!
fuente
Esto comparará los XML de cadena completa (formateándolos en el camino). Facilita el trabajo con su IDE (IntelliJ, Eclipse), ya que simplemente hace clic y visualmente ve la diferencia en los archivos XML.
Prefiero esto a XmlUnit porque el código del cliente (código de prueba) es más limpio.
fuente
El siguiente código me funciona
fuente
Usando JExamXML con la aplicación java
fuente
Requerí la misma funcionalidad solicitada en la pregunta principal. Como no se me permitió usar bibliotecas de terceros, he creado mi propia solución basada en la solución @Archimedes Trajano.
Lo siguiente es mi solución.
Compara dos cadenas XML y se encarga de las asignaciones de espacio de nombres que no coinciden al traducirlas a valores únicos en ambas cadenas de entrada.
Se puede ajustar, es decir, en caso de traducción de espacios de nombres. Pero para mis requisitos solo hace el trabajo.
fuente
Como usted dice "semánticamente equivalente", supongo que quiere decir que quiere hacer algo más que verificar literalmente que las salidas xml son (string) iguales, y que desea algo como
<foo> algunas cosas aquí </foo> </code>
y
<foo> algunas cosas aquí </foo> </code>
lee como equivalente. En última instancia, va a importar cómo se defina "semánticamente equivalente" en cualquier objeto desde el que se reconstituya el mensaje. Simplemente construya ese objeto a partir de los mensajes y use un igual () personalizado para definir lo que está buscando.
fuente