Estou tentando escrever um teste automatizado de um aplicativo que basicamente converte um formato de mensagem personalizado em uma mensagem XML e o envia para o outro lado. Eu tenho um bom conjunto de pares de mensagens de entrada / saída, então tudo o que preciso fazer é enviar as mensagens de entrada e ouvir a mensagem XML sair do outro lado.
Quando chega a hora de comparar a saída real com a saída esperada, estou com alguns problemas. Meu primeiro pensamento foi apenas fazer comparações de string nas mensagens esperadas e reais. Isso não funciona muito bem porque os dados de exemplo que temos nem sempre são formatados de maneira consistente e, muitas vezes, aliases diferentes são usados para o espaço para nome XML (e às vezes os espaços para nome não são usados).
Eu sei que posso analisar as duas strings e, em seguida, percorrer cada elemento e compará-las pessoalmente, e isso não seria muito difícil de fazer, mas sinto que há uma maneira melhor ou uma biblioteca que eu poderia aproveitar.
Então, resumida, a questão é:
Dadas duas Java Strings que contêm XML válido, como você determinaria se elas são semanticamente equivalentes? Pontos de bônus se você tiver uma maneira de determinar quais são as diferenças.
A seguir, será verificado se os documentos são iguais usando as bibliotecas JDK padrão.
normalize () existe para garantir que não haja ciclos (tecnicamente não haveria)
O código acima exigirá que os espaços em branco sejam os mesmos nos elementos, porque ele os preserva e avalia. O analisador XML padrão que acompanha o Java não permite que você configure um recurso para fornecer uma versão canônica ou entenda
xml:space
se isso será um problema; pode ser necessário um analisador XML de substituição, como xerces ou usar JDOM.fonte
setIgnoringElementContentWhitespace(false)
O Xom possui um utilitário Canonicalizer que transforma seus DOMs em um formulário regular, que você pode, então, modificar e comparar. Portanto, independentemente das irregularidades em espaço em branco ou da ordem dos atributos, você pode obter comparações regulares e previsíveis de seus documentos.
Isso funciona especialmente bem em IDEs que possuem comparadores visuais de String dedicados, como o Eclipse. Você obtém uma representação visual das diferenças semânticas entre os documentos.
fonte
A versão mais recente do XMLUnit pode ajudar o trabalho de afirmar que dois XML são iguais. Também
XMLUnit.setIgnoreWhitespace()
eXMLUnit.setIgnoreAttributeOrder()
pode ser necessário para o caso em questão.Veja o código de trabalho de um exemplo simples de uso da Unidade XML abaixo.
Se estiver usando o Maven, adicione-o ao seu
pom.xml
:fonte
Obrigado, eu estendi isso, tente isso ...
fonte
Com base na resposta de Tom , aqui está um exemplo usando o XMLUnit v2.
Ele usa essas dependências automatizadas
..e aqui está o código de teste
A documentação que descreve isso é https://github.com/xmlunit/xmlunit#comparing-two-documents
fonte
skaffman parece estar dando uma boa resposta.
outra maneira é provavelmente formatar o XML usando um utilitário de linha de comando como xmlstarlet ( http://xmlstar.sourceforge.net/ ) e, em seguida, formatar as duas strings e usar qualquer utilitário diff (biblioteca) para diferenciar os arquivos de saída resultantes. Não sei se essa é uma boa solução quando há problemas com namespaces.
fonte
O AssertJ 1.4+ possui asserções específicas para comparar o conteúdo XML:
Aqui está a documentação
fonte
Estou usando o Altova DiffDog, que tem opções para comparar arquivos XML estruturalmente (ignorando dados de string).
Isso significa que (se estiver marcando a opção 'ignorar texto'):
e
são iguais no sentido de que têm igualdade estrutural. Isso é útil se você tiver arquivos de exemplo que diferem nos dados, mas não na estrutura!
fonte
Isso irá comparar XMLs de cadeia completa (reformatando-os no caminho). Isso facilita o trabalho com seu IDE (IntelliJ, Eclipse), pois você apenas clica e vê visualmente a diferença nos arquivos XML.
Eu prefiro isso ao XmlUnit porque o código do cliente (código de teste) é mais limpo.
fonte
O código abaixo funciona para mim
fonte
Usando JExamXML com aplicativo java
fonte
Eu exigi a mesma funcionalidade solicitada na pergunta principal. Como eu não tinha permissão para usar nenhuma biblioteca de terceiros, criei minha própria solução com base na solução @Archimedes Trajano.
A seguir está a minha solução.
Ele compara duas cadeias XML e cuida de qualquer mapeamento de espaço de nome incompatível, convertendo-as em valores exclusivos nas duas cadeias de entrada.
Pode ser ajustado, ou seja, no caso de tradução de namespaces. Mas, para os meus requisitos, apenas faz o trabalho.
fonte
Como você diz "equivalente semanticamente", suponho que você queira fazer mais do que apenas literalmente verificar se as saídas xml são (string) iguais e se deseja algo como
<foo> algumas coisas aqui </foo> </code>
e
<foo> algumas coisas aqui </foo> </code>
leia como equivalente. Por fim, importa como você está definindo "equivalente semanticamente" em qualquer objeto do qual reconstituir a mensagem. Simplesmente crie esse objeto a partir das mensagens e use um igual igual a () para definir o que você está procurando.
fonte