Wednesday, March 9, 2016

XMLUnit

XMLUnit provides convenient APIs to write test-cases. Here is the user guide.

Below mentioned is some of the sample test cases with xmlunit.

import org.custommonkey.xmlunit.*;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Node;

import java.util.List;

/** * Created by pbhavsar on 3/7/16. */public class XmlUnitTest {

    @Test    public void xmlunitunderstadning_whenxsiTypeisPresent_shouldfail() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><thumbnailInfo></thumbnailInfo></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><thumbnailInfo xmlns:xsi=\"http://www.w3.org/2001\" xsi:type=\"simpleCollageProduct\"></thumbnailInfo></SimpleCollageApplicationSummary>";
        Diff diff = new Diff(myControlXML,myTestXML);
        XMLAssert.assertXMLEqual(diff,true);
    }

    @Test    public void xmlunitUnderstanding_between_similiar_and_identical() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><thumbnailInfo><isLandscape>true</isLandscape><layoutID>77480</layoutID></thumbnailInfo></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><thumbnailInfo><layoutID>77480</layoutID><isLandscape>true</isLandscape></thumbnailInfo></SimpleCollageApplicationSummary>";
        Diff diff = new Diff(myControlXML,myTestXML);
        XMLUnit.setIgnoreAttributeOrder(false);
        XMLAssert.assertXMLEqual(diff,true);
    }

    @Test    public void difference_between_similiar_and_identical() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><thumbnailInfo><isLandscape>true</isLandscape><layoutID>77480</layoutID></thumbnailInfo></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><thumbnailInfo><layoutID>77480</layoutID><isLandscape>true</isLandscape></thumbnailInfo></SimpleCollageApplicationSummary>";
        Diff diff = new Diff(myControlXML,myTestXML);
        Assert.assertTrue("test xml matches control xml", diff.similar());
        Assert.assertFalse("test xml matches control xml", diff.identical());
    }

    @Test    public void difference_between_similiar_and_identical_not_applicable_for_attribute_name_based_sequence_difference() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><summaryProperty key=\"occasionId\" value=\"38\" /><summaryProperty key=\"sizeId\" value=\"304\" /></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><summaryProperty key=\"sizeId\" value=\"304\" /><summaryProperty key=\"occasionId\" value=\"38\" /></SimpleCollageApplicationSummary>";
        XMLUnit.setIgnoreAttributeOrder(false);
        Diff diff = new Diff(myControlXML,myTestXML);
        diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
        Assert.assertTrue("test xml matches control xml", diff.similar());
    }

    @Test    public void xmlunitunderstadning_detailed_differences() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><thumbnailInfo></thumbnailInfo></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><thumbnailInfo xmlns:xsi=\"http://www.w3.org/2001\" xsi:type=\"simpleCollageProduct\"></thumbnailInfo></SimpleCollageApplicationSummary>";
        DetailedDiff diff = new DetailedDiff(new Diff(myControlXML,myTestXML));
        List allDifferences = diff.getAllDifferences();
        System.out.println(allDifferences.isEmpty());
        for(Object obj : allDifferences) {
            Difference difference = (Difference)obj;
            System.out.println(difference.getControlNodeDetail().getNode().getNodeName());
            System.out.println(difference.getControlNodeDetail().getXpathLocation());
            System.out.println(difference.getId());
        }
        XMLAssert.assertXMLNotEqual(myControlXML,myTestXML);
    }

    @Test    public void xmlunitunderstadning_custom_implementation() throws Exception {
        String myControlXML = "<SimpleCollageApplicationSummary><thumbnailInfo></thumbnailInfo></SimpleCollageApplicationSummary>";
        String myTestXML = "<SimpleCollageApplicationSummary><thumbnailInfo xmlns:xsi=\"http://www.w3.org/2001\" xsi:type=\"simpleCollageProduct\"></thumbnailInfo></SimpleCollageApplicationSummary>";
        MyTextAndAttributeListener listener = new MyTextAndAttributeListener();
        Diff diff = new Diff(myControlXML,myTestXML);
        diff.overrideDifferenceListener(new CloseEnoughDifferenceListener());
        XMLAssert.assertXMLEqual("Both are not equal ", diff,true);
    }


}

class MyTextAndAttributeListener implements DifferenceListener {
    private static final int[] IGNORE_VALUES = new int[] {
            DifferenceConstants.ATTR_NAME_NOT_FOUND_ID,
            DifferenceConstants.ELEMENT_NUM_ATTRIBUTES_ID    };

    private boolean isIgnoredDifference(Difference difference) {
        int differenceId = difference.getId();
        for (int i=0; i < IGNORE_VALUES.length; ++i) {
            if (differenceId == IGNORE_VALUES[i] && difference.getTestNodeDetail().getNode().getNodeName().equalsIgnoreCase("thumbnailInfo")) {
                return true;
            }
        }
        return false;
    }

    /**     * @return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR to ignore     *  differences in values of TEXT or ATTRIBUTE nodes,     *  and RETURN_ACCEPT_DIFFERENCE to accept all other     *  differences.     * @see DifferenceListener#differenceFound(Difference)     */    public int differenceFound(Difference difference) {
        if (isIgnoredDifference(difference)) {
            return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
        } else {
            return RETURN_ACCEPT_DIFFERENCE;
        }
    }

    /**     * Do nothing     * @see DifferenceListener#skippedComparison(Node, Node)     */    public void skippedComparison(Node control, Node test) {
        System.out.println(test.getNodeName());
    }

}


import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.DifferenceConstants;
import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.NodeDetail;
import org.w3c.dom.Node;

import java.util.Arrays;

/** * Copyright (c) Shutterfly, Inc. 2016.  All Rights Reserved. * */public class CloseEnoughDifferenceListener implements DifferenceListener {

    private static final int[] IGNORE = new int[] {
        DifferenceConstants.CHILD_NODELIST_SEQUENCE_ID,
            DifferenceConstants.ELEMENT_NUM_ATTRIBUTES_ID,
    };

    private int skipCount = 0;

    @Override    public int differenceFound(Difference difference) {
        int differenceId = difference.getId();

        // xmlns:xsi attribute as it is associated with thumbnailInfo only        if(differenceId == DifferenceConstants.ELEMENT_NUM_ATTRIBUTES_ID &&
                difference.getTestNodeDetail().getXpathLocation().equals("/SimpleCollageApplicationSummary[1]/thumbnailInfo[1]")) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }

        // node children does not match as thumnailInfo has missing xsi:type in control node        if(differenceId == DifferenceConstants.CHILD_NODELIST_LENGTH_ID &&
                (difference.getTestNodeDetail().getXpathLocation().equals("/SimpleCollageApplicationSummary[1]/thumbnailInfo[1]/@type") ||
                        (Integer.parseInt(difference.getTestNodeDetail().getValue()) - Integer.parseInt(difference.getControlNodeDetail().getValue()) <= 2))) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }

        // if childSkus is present as empty element in control node and not present in test node        if(differenceId == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID && difference.getControlNodeDetail().getValue().equals("childSkus") &&
                difference.getControlNodeDetail().getNode().getNextSibling()==null &&
                difference.getTestNodeDetail().getNode() == null) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }

        // xsi:type associated with thumbnailInfo if not found        if(differenceId == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID &&
                difference.getTestNodeDetail().getXpathLocation().equals("/SimpleCollageApplicationSummary[1]/thumbnailInfo[1]/@type")) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }

        // if pageNumber value is zero, node is not present        if(difference.getControlNodeDetail().getNode() == null && difference.getTestNodeDetail().getNode().getNodeName().equals("pageNumber") &&
                Integer.parseInt(difference.getTestNodeDetail().getNode().getFirstChild().getNodeValue())==0) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }

        if (Arrays.binarySearch(IGNORE, difference.getId()) >= 0)
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;

        String diff = describeDiff(difference);
        System.out.println(diff);

        return RETURN_ACCEPT_DIFFERENCE;
    }

    @Override    public void skippedComparison(Node node, Node node1) {
        skipCount += 1;
    }

    private String describeDiff(Difference difference) {
        NodeDetail control = difference.getControlNodeDetail();
        NodeDetail test = difference.getTestNodeDetail();

        return control.getXpathLocation() +
               ": expected " + control.getValue() +
               " but got " + test.getValue() +
               " (" + difference.getDescription() + ")\n";
    }

    public int getSkipCount() {
        return skipCount;
    }
}



No comments:

Post a Comment