diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
new file mode 100644
index 0000000..138d22d
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.xml;
+
+import org.onosproject.yang.YangModel;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.runtime.AppModuleInfo;
+import org.onosproject.yang.runtime.DefaultAppModuleInfo;
+import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.ymrimpl.DefaultYangModelRegistry;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.deSerializeDataModel;
+import static org.onosproject.yang.compiler.plugin.utils.YangApacheUtils.processModuleId;
+import static org.onosproject.yang.compiler.plugin.utils.YangApacheUtils.processYangModel;
+import static org.onosproject.yang.compiler.utils.UtilConstants.TEMP;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;
+import static org.onosproject.yang.runtime.helperutils.RuntimeHelper.getInterfaceClassName;
+
+/**
+ * Represents mock bundle context. provides bundle context for YSR to do unit
+ * testing.
+ */
+public class MockYangSchemaNodeProvider {
+
+    private static final String FS = File.separator;
+    private static final String PATH = System.getProperty("user.dir") +
+            FS + "target" + FS + "classes" + FS;
+    private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+            FS + "YangMetaData.ser";
+    private static final String META_PATH = PATH + SER_FILE_PATH;
+    private static final String TEMP_FOLDER_PATH = PATH + TEMP;
+    private YangModelRegistry reg = new DefaultYangModelRegistry();
+    private List<YangNode> nodes = new ArrayList<>();
+
+    /**
+     * Creates an instance of mock bundle context.
+     */
+    public MockYangSchemaNodeProvider() {
+    }
+
+    /**
+     * Process YANG schema node for a application.
+     */
+    public void processSchemaRegistry() {
+        try {
+            //Need to deserialize generated meta data file for unit tests.
+            Set<YangNode> appNode = deSerializeDataModel(META_PATH);
+            nodes.addAll(appNode);
+            reg.registerModel(prepareParam(nodes));
+            deleteDirectory(TEMP_FOLDER_PATH);
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Unregister given nodes from runtime service.
+     *
+     * @param nodes list of nodes
+     */
+    public void unRegister(List<YangNode> nodes) {
+        reg.unregisterModel(prepareParam(nodes));
+    }
+
+    /**
+     * Prepares model registration parameter.
+     *
+     * @param nodes list of nodes
+     * @return model registration parameter
+     */
+    private ModelRegistrationParam prepareParam(List<YangNode> nodes) {
+        //Process loading class file.
+        String appName;
+        ClassLoader classLoader = getClass().getClassLoader();
+
+        //Create model registration param.
+        ModelRegistrationParam.Builder b =
+                DefaultModelRegistrationParam.builder();
+
+        //create a new YANG model
+        YangModel model = processYangModel(META_PATH, nodes);
+        //set YANG model
+        b.setYangModel(model);
+
+        Iterator<YangNode> it = nodes.iterator();
+        while (it.hasNext()) {
+            YangSchemaNode node = it.next();
+
+            //If service class is not generated then use
+            // interface file to load this class.
+            appName = getInterfaceClassName(node);
+            Class<?> cls;
+            try {
+                cls = classLoader.loadClass(appName);
+            } catch (ClassNotFoundException e) {
+                continue;
+            }
+
+            //generate app info.
+            AppModuleInfo info = new DefaultAppModuleInfo(cls, null);
+            b.addAppModuleInfo(processModuleId((YangNode) node), info);
+        }
+        return b.build();
+    }
+
+    /**
+     * Returns schema registry.
+     *
+     * @return schema registry
+     */
+    public DefaultYangModelRegistry registry() {
+        return (DefaultYangModelRegistry) reg;
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
new file mode 100644
index 0000000..dfc8d06
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.xml;
+
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.YangSerializerContext;
+import org.onosproject.yang.runtime.ymrimpl.DefaultYangModelRegistry;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Tests the default schema context provider methods.
+ */
+public class MockYangSerializerContext implements YangSerializerContext {
+
+    private static MockYangSchemaNodeProvider schemaProvider =
+            new MockYangSchemaNodeProvider();
+    private static final String NETCONF_NS =
+            "urn:ietf:params:xml:ns:netconf:base:1.0";
+    private static final String XMNLS_NC = "xmlns:xc";
+
+
+    @Override
+    public SchemaContext getContext() {
+        schemaProvider.processSchemaRegistry();
+        DefaultYangModelRegistry registry = schemaProvider.registry();
+        return registry;
+    }
+
+    @Override
+    public List<Annotation> getProtocolAnnotations() {
+        Annotation annotation = new DefaultAnnotation(XMNLS_NC, NETCONF_NS);
+        List<Annotation> protocolAnnotation = new LinkedList<>();
+        protocolAnnotation.add(annotation);
+        return protocolAnnotation;
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
new file mode 100644
index 0000000..1f53ac5
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.xml;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.LeafListKey;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.SchemaId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+import org.onosproject.yang.runtime.YangSerializer;
+import org.onosproject.yang.runtime.YangSerializerContext;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ *
+ */
+public class XmlSerializerTest {
+
+    private static YangSerializerContext context;
+    private static YangSerializer xmlSerializer;
+
+    @BeforeClass
+    public static void prepare() {
+        context = new MockYangSerializerContext();
+        xmlSerializer = new XmlSerializer();
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG container.
+     */
+    @Test
+    public void testContainer() {
+        String path = "src/test/resources/testContainer.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode food = validateContainerDataNode(rootNode, "food", "yrt:food");
+        validateLeafDataNode(food, "p1", "yrt:food", "p1_value");
+        validateLeafListDataNode(food, "p2", "yrt:food", "p2_value");
+        validateLeafListDataNode(food, "p2", "yrt:food", "p2_value1");
+        DataNode c2 = validateContainerDataNode(rootNode, "c2", "yrt:food");
+        validateLeafDataNode(c2, "p3", "yrt:food", "p3_value");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG leaf.
+     */
+    @Test
+    public void testModuleLevelLeaf() {
+        String path = "src/test/resources/testModuleLevelLeaf.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        validateLeafDataNode(rootNode, "bool", "yrt:food", "true");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG list.
+     */
+    @Test
+    public void testListWithKeyleaves() {
+        String path = "src/test/resources/testListWithKeyleaves.xml";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        List<String> keyNames = new LinkedList<>();
+        keyNames.add("k1");
+        keyNames.add("k2");
+        keyNames.add("k3");
+
+        List<String> keyNs = new LinkedList<>();
+        keyNs.add("yrt:list");
+        keyNs.add("yrt:list");
+        keyNs.add("yrt:list");
+
+        List<Object> values = new LinkedList<>();
+        values.add("k1_Value");
+        values.add("k2_Value");
+        values.add("k3_Value");
+
+        DataNode listl1 = validateListDataNode(rootNode, "l1", "yrt:list",
+                                               keyNames, keyNs, values);
+        validateLeafDataNode(listl1, "k1", "yrt:list", "k1_Value");
+        validateLeafDataNode(listl1, "k2", "yrt:list", "k2_Value");
+        validateLeafDataNode(listl1, "k3", "yrt:list", "k3_Value");
+        DataNode c1 = validateContainerDataNode(listl1, "c1", "yrt:list");
+        validateLeafDataNode(c1, "leaf_c1", "yrt:list", "l1_value");
+
+        values = new LinkedList<>();
+        values.add("k1_Value1");
+        values.add("k2_Value2");
+        values.add("k3_Value3");
+
+        DataNode listl2 = validateListDataNode(rootNode, "l1", "yrt:list",
+                                               keyNames, keyNs, values);
+        validateLeafDataNode(listl2, "k1", "yrt:list", "k1_Value1");
+        validateLeafDataNode(listl2, "k2", "yrt:list", "k2_Value2");
+        validateLeafDataNode(listl2, "k3", "yrt:list", "k3_Value3");
+        c1 = validateContainerDataNode(listl2, "c1", "yrt:list");
+        validateLeafDataNode(c1, "leaf_c1", "yrt:list", "l1_value1");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is child of YANG
+     * choice-case.
+     */
+    @Test
+    public void testChoiceCase() {
+        String path = "src/test/resources/testChoiceCase.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode list1 = validateListDataNode(rootNode, "banana",
+                                              "yrt:choice-case", null, null, null);
+        validateLeafDataNode(list1, "l1", "yrt:choice-case", "value2");
+        DataNode coldDrink = validateContainerDataNode(rootNode, "cold-drink",
+                                                       "yrt:choice-case");
+        validateLeafListDataNode(coldDrink, "flavor", "yrt:choice-case",
+                                 "value3");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of YANG augmented nodes.
+     */
+    @Test
+    public void testAugment() {
+        String path = "src/test/resources/testAugment.xml";
+
+        String uri = "urn:ietf:params:xml:ns:yang:yrt-ietf-network:networks/network/node";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(uri, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        ResourceData resourceData = compositeData.resourceData();
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        DataNode dataNode = dataNodes.get(0);
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is("t-point"));
+        assertThat(schemaId.namespace(), is("urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology"));
+        validateLeafDataNode(dataNode, "tp-id",
+                             "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology", "Stub");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is child of YANG grouping.
+     */
+    @Test
+    public void testGroupingUsesDataNode() {
+        String path = "src/test/resources/testGroupingUses.xml";
+
+        String uri = "urn:ietf:params:xml:ns:yang:yrt-ietf-network:networks-state/network";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(uri, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        ResourceData resourceData = compositeData.resourceData();
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        LeafNode dataNode = ((LeafNode) dataNodes.get(0));
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is("network-ref"));
+        assertThat(schemaId.namespace(), is("urn:ietf:params:xml:ns:yang:yrt-ietf-network"));
+        assertThat(dataNode.value().toString(), is("abc"));
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates whether XML attributes is converted to annotations.
+     */
+    @Test
+    public void testXmlAttributes() {
+        String path = "src/test/resources/testXmlAttributes.xml";
+        String namespace = "http://example.com/schema/1.2/config";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode top = validateContainerDataNode(rootNode, "top", namespace);
+        DataNode interfaceDn = validateContainerDataNode(top, "interface",
+                                                         namespace);
+        validateLeafDataNode(interfaceDn, "name", namespace, "Ethernet0/0");
+        validateLeafDataNode(interfaceDn, "mtu", namespace, "1500");
+        DataNode address = validateContainerDataNode(interfaceDn, "address",
+                                                     namespace);
+        validateLeafDataNode(address, "name", namespace, "192.0.2.4");
+        validateLeafDataNode(address, "prefix-length", namespace, "24");
+
+        List<AnnotatedNodeInfo> annotatedNodeInfos = compositeData
+                .annotatedNodesInfo();
+        AnnotatedNodeInfo annotatedNodeInfo = annotatedNodeInfos.get(0);
+        List<Annotation> annotationList = annotatedNodeInfo.annotations();
+        Annotation annotation = annotationList.get(0);
+        assertThat(annotation.name(), is("xc:operation"));
+        assertThat(annotation.value(), is("replace"));
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates and returns container data node.
+     *
+     * @param parent    data node holding container
+     * @param name      name of the container
+     * @param namespace namespace of the container
+     * @return container data node
+     */
+    private static DataNode validateContainerDataNode(DataNode parent,
+                                                      String name,
+                                                      String namespace) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        DataNode dataNode = childNodes.get(key);
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        return dataNode;
+    }
+
+    /**
+     * Validates and returns list data node.
+     *
+     * @param parent    data node holding list
+     * @param name      name of the list
+     * @param namespace namespace of the list
+     * @param keynames  list of key leaf names
+     * @param keyNs     list of key leaf namespace
+     * @param keyVal    list of key leaf values
+     * @return list data node
+     */
+    private static DataNode validateListDataNode(DataNode parent,
+                                                 String name, String namespace,
+                                                 List<String> keynames,
+                                                 List<String> keyNs,
+                                                 List<Object> keyVal) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        DataNode dataNode;
+        if (keynames != null && !keynames.isEmpty()) {
+            ListKey.ListKeyBuilder listKeyBldr = new ListKey.ListKeyBuilder();
+            listKeyBldr.schemaId(key.schemaId());
+            for (int i = 0; i < keynames.size(); i++) {
+                listKeyBldr.addKeyLeaf(keynames.get(i), keyNs.get(i),
+                                       keyVal.get(i));
+            }
+            dataNode = childNodes.get(listKeyBldr.build());
+        } else {
+            dataNode = childNodes.get(key);
+        }
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        return dataNode;
+    }
+
+    /**
+     * Validates leaf data node.
+     *
+     * @param parent    data node holding leaf
+     * @param name      name of the leaf
+     * @param namespace namespace of the leaf
+     * @param value     leaf value
+     */
+    private static void validateLeafDataNode(DataNode parent,
+                                             String name, String namespace,
+                                             Object value) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        LeafNode dataNode = ((LeafNode) childNodes.get(key));
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        assertThat(dataNode.value().toString(), is(value));
+    }
+
+    /**
+     * Validates leaf-list data node.
+     *
+     * @param parent    data node holding leaf-list
+     * @param name      name of the leaf-list
+     * @param namespace namespace of the leaf-list
+     * @param value     leaf-list value
+     */
+    private static void validateLeafListDataNode(DataNode parent,
+                                                 String name, String namespace,
+                                                 Object value) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        LeafListKey.LeafListKeyBuilder leafListBldr =
+                new LeafListKey.LeafListKeyBuilder();
+        leafListBldr.schemaId(key.schemaId());
+        leafListBldr.value(value);
+        DataNode leafListNode = childNodes.get(leafListBldr.build());
+        SchemaId schemaId = leafListNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        assertThat(((LeafNode) leafListNode).value().toString(), is(value));
+    }
+
+    /**
+     * Validates root data node.
+     *
+     * @param resourceData resource data which holds data node
+     * @return root data node
+     */
+    private static DataNode validateRootDataNode(ResourceData resourceData) {
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        DataNode rootNode = dataNodes.get(0);
+        SchemaId rootSchemaId = rootNode.key().schemaId();
+        assertThat(rootSchemaId.name(), is("/"));
+        return rootNode;
+    }
+
+    /**
+     * Reads XML contents from file path and returns input stream.
+     *
+     * @param path path of XML file
+     * @return input stream
+     */
+    private static InputStream parseInput(String path) {
+        String temp;
+        StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+            while ((temp = br.readLine()) != null) {
+                sb.append(temp);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return IOUtils.toInputStream(sb);
+    }
+
+    /**
+     * Reads XML contents from file path and returns input stream.
+     *
+     * @param path path of XML file
+     * @return input stream
+     */
+    private static String parseXml(String path) {
+        String temp;
+        StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+            while ((temp = br.readLine()) != null) {
+                sb.append(temp);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Converts input stream to string format.
+     *
+     * @param inputStream input stream of xml
+     * @return XML string
+     */
+    private static String convertInputStreamToString(InputStream inputStream) {
+        BufferedReader br;
+        StringBuilder sb = new StringBuilder();
+        String xmlData;
+        br = new BufferedReader(new InputStreamReader(inputStream));
+        try {
+            while ((xmlData = br.readLine()) != null) {
+                sb.append(xmlData);
+            }
+        } catch (IOException e) {
+            throw new XmlSerializerException(e.getMessage());
+        }
+        return sb.toString();
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java
new file mode 100644
index 0000000..43b4abc
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *  Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * The XML serializer implementation of the YangSerializer interface.
+ */
+package org.onosproject.yang.serializers.xml;
diff --git a/serializers/xml/src/test/resources/testAugment.xml b/serializers/xml/src/test/resources/testAugment.xml
new file mode 100644
index 0000000..4c883f6
--- /dev/null
+++ b/serializers/xml/src/test/resources/testAugment.xml
@@ -0,0 +1,3 @@
+<t-point xmlns="urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology">
+<tp-id>Stub</tp-id>
+</t-point>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testChoiceCase.xml b/serializers/xml/src/test/resources/testChoiceCase.xml
new file mode 100644
index 0000000..22590a1
--- /dev/null
+++ b/serializers/xml/src/test/resources/testChoiceCase.xml
@@ -0,0 +1,6 @@
+<banana xmlns="yrt:choice-case">
+<l1>value2</l1>
+</banana>
+<cold-drink xmlns="yrt:choice-case">
+<flavor>value3</flavor>
+</cold-drink>
diff --git a/serializers/xml/src/test/resources/testContainer.xml b/serializers/xml/src/test/resources/testContainer.xml
new file mode 100644
index 0000000..ee679b8
--- /dev/null
+++ b/serializers/xml/src/test/resources/testContainer.xml
@@ -0,0 +1,8 @@
+<food xmlns="yrt:food">
+<p1>p1_value</p1>
+<p2>p2_value</p2>
+<p2>p2_value1</p2>
+</food>
+<c2 xmlns="yrt:food">
+<p3>p3_value</p3>
+</c2>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testGroupingUses.xml b/serializers/xml/src/test/resources/testGroupingUses.xml
new file mode 100644
index 0000000..45d3d05
--- /dev/null
+++ b/serializers/xml/src/test/resources/testGroupingUses.xml
@@ -0,0 +1,2 @@
+<network-ref xmlns="urn:ietf:params:xml:ns:yang:yrt-ietf-network">abc
+</network-ref>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testListWithKeyleaves.xml b/serializers/xml/src/test/resources/testListWithKeyleaves.xml
new file mode 100644
index 0000000..1f9616a
--- /dev/null
+++ b/serializers/xml/src/test/resources/testListWithKeyleaves.xml
@@ -0,0 +1,16 @@
+<l1 xmlns="yrt:list" operation="replace">
+<k1>k1_Value</k1>
+<k2>k2_Value</k2>
+<k3>k3_Value</k3>
+<c1>
+<leaf_c1>l1_value</leaf_c1>
+</c1>
+</l1>
+<l1 xmlns="yrt:list" operation="replace">
+<k1>k1_Value1</k1>
+<k2>k2_Value2</k2>
+<k3>k3_Value3</k3>
+<c1>
+<leaf_c1>l1_value1</leaf_c1>
+</c1>
+</l1>
diff --git a/serializers/xml/src/test/resources/testModuleLevelLeaf.xml b/serializers/xml/src/test/resources/testModuleLevelLeaf.xml
new file mode 100644
index 0000000..13da6e6
--- /dev/null
+++ b/serializers/xml/src/test/resources/testModuleLevelLeaf.xml
@@ -0,0 +1,2 @@
+<bool xmlns="yrt:food">true</bool>
+<boolean xmlns="yrt:food">true</boolean>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testMultipleLevelAugment.xml b/serializers/xml/src/test/resources/testMultipleLevelAugment.xml
new file mode 100644
index 0000000..ab31d06
--- /dev/null
+++ b/serializers/xml/src/test/resources/testMultipleLevelAugment.xml
@@ -0,0 +1,6 @@
+<interface xmlns="ser.ospf" operation="replace">
+<area-type>Stub</area-type>
+</interface>
+<statistics xmlns="ser.ospf" operation="replace">
+<spf-runs-count>3</spf-runs-count>
+</statistics>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testXmlAttributes.xml b/serializers/xml/src/test/resources/testXmlAttributes.xml
new file mode 100644
index 0000000..0ca9a71
--- /dev/null
+++ b/serializers/xml/src/test/resources/testXmlAttributes.xml
@@ -0,0 +1,10 @@
+<top xmlns="http://example.com/schema/1.2/config">
+<interface xc:operation="replace">
+<name>Ethernet0/0</name>
+<mtu>1500</mtu>
+<address>
+<name>192.0.2.4</name>
+<prefix-length>24</prefix-length>
+</address>
+</interface>
+</top>
\ No newline at end of file
