xmlschema www org xml unit-testing language-agnostic dtd

www - ¿La mejor forma de validar XML en una prueba unitaria?



http www w3 org 2001 xmlschema (3)

Tengo una clase con un método ToString que produce XML. Quiero probarlo por unidad para asegurarme de que está produciendo xml válido. Tengo una DTD para validar el XML en contra.

¿Debería incluir la DTD como una cadena dentro de la prueba de la unidad para evitar una dependencia de ella, o existe una forma más inteligente de hacerlo?


He usado XmlUnit en el pasado y lo encontré útil.

Se puede usar para validar XML en un esquema o comparar su XML con una cadena. Es lo suficientemente inteligente como para entender las reglas de análisis de XML. Por ejemplo, sabe que "<e1 />" es equivalente a "<e1> </ e1>" y se puede configurar para ignorar o incluir espacios en blanco.


Si su programa valida el XML en contra de la DTD durante la ejecución normal, entonces simplemente debe obtener la DTD donde sea que su programa la obtenga.

Si no es así y el DTD es extremadamente corto (solo unas pocas líneas), entonces almacenarlo como una cadena en su código probablemente sea correcto.

De lo contrario, lo pondría en un archivo externo y su unidad de prueba lo leería de ese archivo.


Usar una DTD en la prueba unitaria para probar su validez es una cosa, la prueba para el contenido correcto es otra.

Puede usar el DTD para verificar la validez del xml generado, que simplemente leería de la manera en que lo hace en su programa. Personalmente no lo incluiría en línea (como una cadena); siempre hay una dependencia entre el código de la aplicación y la prueba de la unidad. Cuando el xml generado cambia, la DTD también cambiará.

Para probar el contenido correcto, me gustaría ir a XMLUnit .

Aserción de xml usando XMLUnit:

XMLUnit.setIgnoreWhitespace(true); XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true); Diff diff = new Diff(expectedDocument, obtainedDocument); XMLAssert.assertXMLIdentical("xml invalid", diff, true);

Una cosa con la que se puede encontrar es que el xml generado podría contener identificadores cambiantes (atributos id / uid o similares). Esto se puede resolver usando un DifferenceListener al afirmar el xml generado.

Ejemplo de implementación de dicho DifferenceListener:

public class IgnoreVariableAttributesDifferenceListener implements DifferenceListener { private final List<String> IGNORE_ATTRS; private final boolean ignoreAttributeOrder; public IgnoreVariableAttributesDifferenceListener(List<String> attributesToIgnore, boolean ignoreAttributeOrder) { this.IGNORE_ATTRS = attributesToIgnore; this.ignoreAttributeOrder = ignoreAttributeOrder; } @Override public int differenceFound(Difference difference) { // for attribute value differences, check for ignored attributes if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID) { if (IGNORE_ATTRS.contains(difference.getControlNodeDetail().getNode().getNodeName())) { return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } } // attribute order mismatch (optionally ignored) else if (difference.getId() == DifferenceConstants.ATTR_SEQUENCE_ID && ignoreAttributeOrder) { return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } // attribute missing / not expected else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) { if (IGNORE_ATTRS.contains(difference.getTestNodeDetail().getValue())) { return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } } return RETURN_ACCEPT_DIFFERENCE; } @Override public void skippedComparison(Node control, Node test) { // nothing to do } }

usando DifferenceListener:

XMLUnit.setIgnoreWhitespace(true); XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true); Diff diff = new Diff(expectedDocument, obtainedDocument); diff.overrideDifferenceListener(new IgnoreVariableAttributesDifferenceListener(Arrays.asList("id", "uid"), true)); XMLAssert.assertXMLIdentical("xml invalid", diff, true);