단위 테스트에서 XML의 유효성을 검사하는 가장 좋은 방법은 무엇입니까?
-
09-06-2019 - |
문제
나는 수업이 있어요 ToString
XML을 생성하는 메서드입니다.유효한 XML을 생성하는지 확인하기 위해 단위 테스트를 원합니다.XML의 유효성을 검사할 DTD가 있습니다.
종속성을 피하기 위해 단위 테스트 내에 DTD를 문자열로 포함해야 합니까? 아니면 더 똑똑한 방법이 있나요?
해결책
프로그램이 일반 실행 중에 DTD에 대해 XML의 유효성을 검사하는 경우 프로그램이 DTD를 얻을 수 있는 곳에서 DTD를 가져와야 합니다.
그렇지 않고 DTD가 매우 짧다면(단 몇 줄) 코드에 문자열로 저장하는 것이 아마도 괜찮을 것입니다.
그렇지 않으면 외부 파일에 넣고 단위 테스트에서 해당 파일에서 읽도록 합니다.
다른 팁
나는 사용했다 Xml단위 과거에는 그것이 유용하다고 생각했습니다.
스키마에 대해 XML의 유효성을 검사하거나 XML을 문자열과 비교하는 데 사용할 수 있습니다.XML의 구문 분석 규칙을 이해하는 것은 충분히 영리합니다.예를 들어 "<e1/>"은 "<e1></e1>"과 동일하며 공백을 무시하거나 포함하도록 구성할 수 있다는 것을 알고 있습니다.
단위 테스트에서 DTD를 사용하여 유효성을 테스트하는 것과 올바른 내용을 테스트하는 것은 또 다른 것입니다.
DTD를 사용하여 생성된 XML의 유효성을 확인할 수 있습니다. 이는 프로그램에서 수행하는 방식으로 간단하게 읽을 수 있습니다.나는 개인적으로 그것을 인라인(문자열로)에 포함시키지 않을 것입니다.애플리케이션 코드와 단위 테스트 사이에는 항상 종속성이 있습니다.생성된 XML이 변경되면 DTD도 변경됩니다.
내가 원하는 올바른 콘텐츠를 테스트하려면 XML단위.
XMLUnit을 사용하여 xml을 어설션:
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
Diff diff = new Diff(expectedDocument, obtainedDocument);
XMLAssert.assertXMLIdentical("xml invalid", diff, true);
여러분이 접할 수 있는 한 가지는 생성된 XML에 변경 식별자(id/uid 속성 등)가 포함될 수 있다는 사실입니다.이 문제는 다음을 사용하여 해결할 수 있습니다. 차이점 청취자 생성된 xml을 어설션할 때.
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
}
}
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);