'Passing data from Jenkins parameterized build to testng.xml at runtime
I have a browser automation framework which uses Java, Maven and TestNG. I am using testng.xml files to pass different parameters to tests in the following way:
<parameter name="firstName" value="John"/>
I want to be able to expose the data inputs to non-technical people and propose to do this by using a parameterized Jenkins job.
All of the test data are Strings.
I can see how I can create a parameterized project in Jenkins and can create String parameters within the project.
I am unclear as to the best way of passing the data at runtime.
I understand an Ant script can be used, but I am using Maven already and don't want to introduce another conflicting technology.
I have heard this can be done using a Beanshell script in the testng.xml but, from the example on the testng docs, I'm still unclear how best to implement this.
Solution 1:[1]
Here's how you can solve this problem.
- Add all the parameters that you want to pass via Jenkins into your suite xml file and define some default values for it.
- In your Jenkins job you now create the parameters but ensure that the name of the parameter in your job configuration matches with the name that you have added in your suite xml file.
- You then make use of a TestNG listener as shown below and then wire it in using one of the methods that are detailed in this blog post of mine
After that, you should be able to easily do what you need. If you are having parameters that are defined at <test> level, then you can enhance the listener I have shown below and add similar code after implementing org.testng.ITestListener listener.
Listener
public class EnvReaderListener implements ISuiteListener {
@Override
public void onStart(ISuite suite) {
Map<String, String> parameters = suite.getXmlSuite().getParameters();
for (Map.Entry<String, String> parameter : parameters.entrySet()) {
String env = System.getenv(parameter.getKey());
if (env != null && ! env.trim().isEmpty()) {
parameter.setValue(env);
}
}
}
@Override
public void onFinish(ISuite suite) {
}
}
TestNG suite xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="My Suite" parallel="methods" verbose="2">
<listeners>
<listener class-name="org.rationale.emotions.EnvReaderListener"/>
</listeners>
<parameter name="name" value="Sample name"/>
<test name="My Test" verbose="2">
<classes>
<class name="org.rationale.emotions.SampleTest"/>
</classes>
</test>
</suite>
As per this example, you would need to ensure that your job would have a parameter named name.
Sample test class
package org.rationale.emotions;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class SampleTest {
@Test
@Parameters ("name")
public void testMethod(String name) {
System.err.println("Name that was passed in via Jenkins job " + name);
}
}
Solution 2:[2]
you may use Maven Resources Plugin goal copy-resources with enabled filters in your project to replace variables in a template file.
Example:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>path_to_output_folder/output</outputDirectory>
<resources>
<resource>
<directory>path_to_resource_dir/res</directory> <!--source to your testng.xml-->
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
in your case for using this with jenkins :
change your testng.xml -->
<parameter name="firstName" value="${firstname}"/>call maven goal
mvn resources:resources -DfirstName=$FIRSTNAMEwhere ($FIRSTNAME) is the Jenkins variable.
hope this helps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Krishnan Mahadevan |
| Solution 2 | Hisham Khalil |
