Multiple test configurations with TestNG
I use TestNG for automated testing as it has a number of
features that JUnit doesn’t have. One of its strengths is the power and
flexibility of configuring tests and supplying parameters to them, for
which there are two methods:
One mechanism is to allow test writers to specify parameters in two files which are merged by Ant into a single testng.xml file before running the tests:
You can invoke the script from Ant with:
- Using the testng.xml file to define both the list of tests to run and parameters.
- Using data providers within your test code to load parameters.
One mechanism is to allow test writers to specify parameters in two files which are merged by Ant into a single testng.xml file before running the tests:
- A testng-default.xml file with the list of tests and default parameters.
- A .properties to supply overrides or additional parameters.
println "Merging testng-default.xml with .properties file into testng.xml" if (args.size() != 3) { println "Script requires three arguments:" println "Path to testng template file" println "Path to .properties file" println "Path for saving merged testng file" } String testNGTemplate = args[0] String propertiesFile = args[1] String mergedTestNGFile = args[2] // get the properties File propsFile = new File(propertiesFile) FileInputStream input = new FileInputStream(propsFile) Properties props = new Properties() props.load(input) // Start copying the testng file File oldTestNG = new File(testNGTemplate) File newTestNG = new File(mergedTestNGFile) // Get the set of parameters. Read in using Groovy XML parser. Node xml = new XmlParser().parse(oldTestNG) NodeList parameterList = xml.test.parameters.parameter // iterate over parameter list and replace any that have been overridden parameterList.each{p -> println p.@name if (props.keySet().contains(p.@name)) { println "Replacing ${p.@name} with value from .properties file" // update the value to the one set in .properties p.@value = props.get(p.@name) } } // Now add any properties that weren't listed in the original // testng-default.xml file Set<String> parameterNames = xml.test.parameters.parameter.@name Node parameters = xml.test.parameters.getAt(0) props.each{ key, value -> if (!parameterNames.contains(key)) { println "Adding property from .properties. Key: ${key}, value: ${value}" parameters.appendNode("parameter",[name: "${key}", value: "${value}"]) } } // Write out the file new XmlNodePrinter(new PrintWriter(newTestNG)).print(xml)Note that this script is written assuming that all of your test classes are part of a single “test”, with the parameters inside that test, like the following:
<suite name="regression-tests"> <test name="regression-basic"> <parameters> <parameter name="param1" value="value1"/> <parameter name="param2" value="value2"/> <parameter name="param3" value="value3"/> </parameters> <classes> <class name="uk.co.somecorp.Test1" /> <class name="uk.co.somecorp.Test2" /> <class name="uk.co.somecorp.Test3" /> </classes> </test> </suite>This is reflected in the lines in the Groovy script that navigate to the parameters, such as:
NodeList parameterList = xml.test.parameters.parameterObviously if you want to organise your default testng file differently you’ll need to adjust these parts of the script.
You can invoke the script from Ant with:
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"> <classpath> <fileset file="/path_to_groovy/groovy-all.jar"/> </classpath> </taskdef> <!-- Target to merge the testng-default.xml and .properties files --> <target name="merge-files"> <groovy src="/path_to_script/MergeTestNGAndProperties.groovy"> <arg value="/some_path/testng-default.xml"/> <arg value="/some_path/my.properties"/> <arg value="/output_path/testng.xml"/> </groovy> </target>
Resoure: