JAXB tutorial for test automation configuration

Java Architecture for XML Binding ( JAXB ) is used to convert XML data into Java Objects or vice versa.

Why Testers need to know about it? If you are using Java in test automation JAXB can be used to convert the test configuration parameters set in XML files to Java Objects and use it in automation.

Setup required: JAXB is a part of Java standard Edition from Java Version 5.x. No special setup required.

Jargons: Marshaling & Un-marshaling

Marshalling: Converting Java Objects to XML data or elements using JAXB is called Marshaling.

Un-marshalling: ConvertingXML data or elements to Java Objects using JAXB is called Un-marshaling.

Most of the test automation requires parameters like application URLĀ , database connection details, browsers needs to be setup. I prefer the following XML format for setting the parameters with the name of the parameter as an attribute rather setting it as the XML element.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<config>
  <parameter name="com.kalaiworld.application.dbHost">            
    <value>kalaiworld.com</value> 
  </parameter> 
  <parameter name="com.kalaiworld.application.dbPassword"> 
    <value>WRE67IYWT90fg</value> 
  </parameter> 
</config>

Lets skip marshalling in this blog as we are going to work on Unmarshalling only for settingĀ configiration parameters.

In the XML above, config element holds the parameter elements and each parameter has name attribute and a value element.

In JAXB we need to map XML elements with corresponding Java classes. XML elements with attributes need to have a separate java class and any elements wrapped in those elements can also be mapped in the same class.

The XML element – config cannot be clubbed with parameter, as parameter has the ‘name‘ attribute where as value can be clubbed with parameter as value does not hold any attribute.

So lets create Parameter.java first. parameter is the root element in this class with the annonation: @XmlRootElement(name=”parameter”) and is mapped to the class name.

@XmlAttribute(name=”name”) has been mapped to getName() method to retrieve the parameter’s name attribute from the XML.

@XmlElement(name=”value”) has been mapped to getValue() method to retrieve parameter’s child element value.

Parameter.java

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

//Mapping to the parameter element in XML
@XmlRootElement(name="parameter")
public class Parameter {
  String value;
  String name;
  //Mapping to the name attribute of parameter element in XML
  @XmlAttribute(name="name")
  public String getName(){
    return name;
  }

  public void setName(String name){
    this.name = name;
  }

  //Mapping to the child element value in XML
  @XmlElement(name="value")
  public String getValue(){
    return value;
  }

  public void setValue(String value){
    this.value=value;
  }
}

@XmlRootElement(name=”parameter”) indicates the root element
The config element can hold as many as parameter elements. so we have to create config class to get List of parameters from XML.

In config class, we will map the parameter element mapped above.

Config.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;

@XmlRootElement(name="config")
public class Config {
  private ArrayList<Parameter> parameter = new ArrayList<Parameter>();

  @XmlElement(name = "parameter")
  public void setParameterList(ArrayList<Parameter> parameterList){
    this.parameter=parameter;
  }

  public ArrayList<Parameter> getParameterList(){
    return parameter;
  }
}

Now you can set any parameter and get its value in your automation by passing the name of the parameter.

Using JAXB Unmarshaller we get the config object holding all the parmeters underneath.

We can retrieve the list of parameters in the config objects by calling getParameterList() method in Config class. Finally you can get the value of your parameter filtering out the list using getName() & its getValue() methods as shown below in the testng test.

ConfigExtractor.java

import org.testng.annotations.Test;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.util.ArrayList;

public class ConfigExtractor {
  @Test
  public void getConfigParameter() throws JAXBException {
    File file=new File("config-example.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(Config.class);
    Unmarshaller unmarshaller=jaxbContext.createUnmarshaller();
    Config config= (Config)unmarshaller.unmarshal(file);
    ArrayList<Parameter> parameterList=config.getParameterList();
    for(Parameter parameter:parameterList){
      if(parameter.getName().equalsIgnoreCase("com.kalaiworld.application.dbPassword")){
         System.out.print(parameter.getValue());
         break;
      }
    }
  }
}

This test prints out the value of the parameter “com.kalaiworld.application.dbPassword” as “WRE67IYWT90fg”

This project is available in my github as a library: https://github.com/kalai0506/configurator

Please post your related queries/suggestion below in comments.