Page History
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package com.xpand.java; import org.testng.Assert; import org.testng.annotations.Test; import org.testng.annotations.BeforeSuite; import org.testng.annotations.AfterSuite; import org.testng.annotations.DataProvider; import org.testng.Reporter; import org.testng.reporters.XMLReporter; import org.testng.ITestResult; import comapp.getxray.xpanditxray.testng.annotations.XrayXrayTest; public class CalcTest { @BeforeSuite public void setUp() throws Exception { } @AfterSuite public void tearDown() throws Exception { } @DataProvider public Object[][] ValidDataProvider() { return new Object[][]{ { 1, 2, 3 }, { 2, 3, 4 }, // error or the data itself :) { -1, 1, 0 } }; } @Test(dataProvider = "ValidDataProvider") @Xray@XrayTest(requirementkey = "CALC-1234", test1") @Requirement(key = "CALC-11234") public void CanAddNumbersFromGivenData(final int a, final int b, final int c) { Assert.assertEquals(Calculator.Add(a, b), c); } @Test @Xray@XrayTest(requirementkey = "CALC-12342", testlabels = "CALC-2", labelscore addition") @Requirement(key = "core additionCALC-1234") public void CanAddNumbers() { Assert.assertEquals(Calculator.Add(1, 1),2); Assert.assertEquals(Calculator.Add(-1, 1),0); } @Test @Xray@XrayTest(requirementlabels = "CALC-1235", labelscore") @Requirement(key = "coreCALC-1235") public void CanSubtract() { Assert.assertEquals(Calculator.Subtract(1, 1), 0); Assert.assertEquals(Calculator.Subtract(-1, -1), 0); Assert.assertEquals(Calculator.Subtract(100, 5), 95); } @Test @Xray@Requirement(requirementkey = "CALC-1236") public void CanMultiplyX() { Assert.assertEquals(Calculator.Multiply(1, 1), 1); Assert.assertEquals(Calculator.Multiply(-1, -1), 1); Assert.assertEquals(Calculator.Multiply(100, 5), 500); } @Test @Xray@Requirement(requirementkey = "CALC-1237") public void CanDivide() { Assert.assertEquals(Calculator.Divide(1, 1), 1); Assert.assertEquals(Calculator.Divide(-1, -1), 1); Assert.assertEquals(Calculator.Divide(100, 5), 20); } @Test public void CanDoStuff() { Assert.assertNotEquals(true, true); } } |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package com.xpandapp.getxray.xray.testng.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * A Custom Annotation to inject additional information into a TestNG Test */ @Retention(RetentionPolicy.RUNTIME) public @interface XrayXrayTest { /** String requirement() default ""; Summary for the Test issue @return a {@code String test() default ""; } containing the Summary's text */ String labelssummary() default ""; /** Description for the Test issue } |
The XrayListener must be defined as a service so TestNG is able to load it at runtime.
Code Block | ||
---|---|---|
| ||
com.xpandit.testng.annotations.XrayListener |
XrayListener class is responsible for processing "Xray" annotation, get the values of some specific attributes and them as attributes to the ITestResult object.
@return a {@code String} containing the Description's text
*/
String description() default "";
/**
issue key of the Test issue to report the results to
@return a {@code String} containing the Summary's text
*/
String key() default "";
/**
labels, delimited by space, for the Test issue
@return a {@code String} containing the labels (one or more)
*/
String labels() default "";
} |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package app.getxray.xray.testng.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* A Custom Annotation to inject additional information into a TestNG Test, related to the covered requirement
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Requirement {
/**
issue key of the requirement (e.g., Story, Epic) to link this test with
@return a {@code String} containing the requirement's issue key
*/
String key() default "";
} |
The XrayListener must be defined as a service so TestNG is able to load it at runtime.
Code Block | ||
---|---|---|
| ||
app.getxray.xray.testng.listeners.XrayListener |
XrayListener class is responsible for processing "Xray" annotation, get the values of some specific attributes and them as attributes to the ITestResult object.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package app.getxray.xray.testng.listeners;
import java.lang.reflect.Method;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.annotations.Test;
import app.getxray.xray.testng.annotations.Requirement;
import app.getxray.xray.testng.annotations.XrayTest;
import static java.lang.System.out;
import static java.lang.System.err;
/**
* The listener interface for receiving events related to execution of tests, and process Xray related annotations.
* The listener can be automatically invoked when TestNG tests are run by using ServiceLoader mechanism.
* You can also add this listener to a TestNG Test class by adding
* <code>@Listeners({app.getxray.testng.XrayListener.class})</code>
* before the test class
*
* @see XrayTest
* @see Requirement
*/
public class XrayListener implements IInvokedMethodListener, ITestListener {
boolean testSuccess = true;
/* (non-Javadoc)
* @see org.testng.IInvokedMethodListener#beforeInvocation(org.testng.IInvokedMethod, org.testng.ITestResult)
*/
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
String summary = null;
String description = null;
String testDescription = null;
String xrayTestDescription = null;
String xrayTestSummary = null;
if (method.isTestMethod()) {
testDescription = method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description();
if (annotationPresent(method, XrayTest.class) ) {
xrayTestDescription = method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(XrayTest.class).description();
xrayTestSummary = method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(XrayTest.class).summary();
testResult.setAttribute("test", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(XrayTest.class).key());
testResult.setAttribute("labels", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(XrayTest.class).labels());
}
if (!emptyString(xrayTestSummary)) {
summary = xrayTestSummary;
} else if (!emptyString(xrayTestDescription) | ||||||
Code Block | ||||||
| ||||||
package com.xpand.annotations; import java.lang.reflect.Method; import org.testng.IInvokedMethod; import org.testng.IInvokedMethodListener; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestNGMethod; import org.testng.ITestResult; import static java.lang.System.out; import static java.lang.System.err; /** * The listener interface for receiving Xray events. * The Listener can be automatically invoked when TestNG tests are run by using ServiceLoader mechanism. * You can also add this listener to a TestNG Test class by adding * <code>@Listeners({com.xpand.java.XrayAnnotationListener.class})</code> * before the test class * * @see Xray */ public class XrayListener implements IInvokedMethodListener, ITestListener { boolean testSuccess = true; /* (non-Javadoc) * @see org.testng.IInvokedMethodListener#beforeInvocation(org.testng.IInvokedMethod, org.testng.ITestResult) */ public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { if(method.isTestMethod() && annotationPresent(method, Xray.class) ) { summary = xrayTestDescription; testResult.setAttribute("requirement", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).requirement()); } else if (!emptyString(testDescription)) { testResult.setAttribute("test", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).test()); summary = xrayTestDescription; } testResult.setAttribute("labels", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).labels()); if (!emptyString(xrayTestDescription)) { } description } = xrayTestDescription; private boolean annotationPresent(IInvokedMethod method, Class clazz} else if (!emptyString(testDescription)) { boolean retVal = method.getTestMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(clazz) ? truedescription := falsetestDescription; return retVal; } /*if (non-Javadoc)(!emptyString(summary)) { * @see org.testng.IInvokedMethodListener#afterInvocation(org.testng.IInvokedMethod, org.testng.ITestResult) testResult.setAttribute("summary", summary); */ public void afterInvocation(IInvokedMethod method, ITestResult testResult) { } if (method.isTestMethod!emptyString(description)) { if( !testSuccess ) { testResult.setAttribute("description", description); } testResult.setStatus(ITestResult.FAILURE); if (annotationPresent(method, Requirement.class) ) }{ } } public void onTestStart(ITestResult result) {testResult.setAttribute("requirement", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Requirement.class).key()); // TODO Auto-generated method stub} } } public void onTestSuccess(ITestResult result) { private boolean annotationPresent(IInvokedMethod method, //Class TODO Auto-generated method stubclazz) { boolean retVal } public void onTestFailure(ITestResult result) { // TODO Auto-generated method stub = method.getTestMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(clazz) ? true : false; return retVal; } publicprivate voidboolean onTestSkippedemptyString(ITestResultString resultstring) { //return TODO Auto-generated method stub (string == null || string.isEmpty() || string.trim().isEmpty()); } public void onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub* (non-Javadoc) * @see org.testng.IInvokedMethodListener#afterInvocation(org.testng.IInvokedMethod, org.testng.ITestResult) } */ public void onStart(ITestContext contextafterInvocation(IInvokedMethod method, ITestResult testResult) { } public void onFinish(ITestContext context if(method.isTestMethod()) { // TODO Auto-generated method stub if( !testSuccess ) { } } |
In Maven's pom.xml
file, we need to make sure test result related attributes are added to the generated XML report. This can be done by setting generateTestResultAttributes
to "true".
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" testResult.setStatus(ITestResult.FAILURE); } } } public void onTestStart(ITestResult result) xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" { } public void xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">onTestSuccess(ITestResult result) { <modelVersion>4.0.0</modelVersion>} <groupId>com.xpand.java</groupId>public void onTestFailure(ITestResult result) { <artifactId>xpand-test</artifactId> <version>1.0-SNAPSHOT</version>} <properties>public void onTestSkipped(ITestResult result) { } public void <!--XRay Properties --> onTestFailedButWithinSuccessPercentage(ITestResult result) { <!--IN PROFILE ~.m2/settings.xml--> } public void onStart(ITestContext <!--<xray.jiraURL></xray.jiraURL>context) { <xray.resultsFormat>JUNIT</xray.resultsFormat> } <xray.username>admin</xray.username> <xray.password>123qwe</xray.password>--> public void onFinish(ITestContext context) { } } |
In Maven's pom.xml
file, we need to make sure test result related attributes are added to the generated XML report. This can be done by setting generateTestResultAttributes
to "true".
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"<xray.projectKey>CALC</xray.projectKey> <!-- <xray.testExecKey></xray.testExecKey> <xray.testPlanKey></xray.testPlanKey> <xray.testEnvironments></xray.testEnvironments> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <xray.revision></xray.revision> --> <xray.surefire.location>${basedir}/target/surefire-reports</xray.surefire.location> <!--End Xray Properties --> </properties> <build> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xpand.java</groupId> <artifactId>xpand-test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <plugins><!--XRay Properties --> <!--IN <plugin>PROFILE ~.m2/settings.xml--> <!--<xray.jiraURL></xray.jiraURL> <artifactId>maven-compiler-plugin</artifactId><xray.resultsFormat>JUNIT</xray.resultsFormat> <xray.username>admin</xray.username> <configuration><xray.password>123qwe</xray.password>--> <xray.projectKey>CALC</xray.projectKey> <debug>true</debug><!-- <xray.testExecKey></xray.testExecKey> <source>1.8</source><xray.testPlanKey></xray.testPlanKey> <xray.testEnvironments></xray.testEnvironments> <target>1<xray.8<revision></target>xray.revision> --> </configuration> <xray.surefire.location>${basedir}/target/surefire-reports</xray.surefire.location> <!--End Xray Properties --> </plugin>properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <version>2.20.1</version> <debug>true</debug> <configuration> <source>1.8</source> <testFailureIgnore>true</testFailureIgnore> <target>1.8</target> <suiteXmlFiles></configuration> </plugin> <suiteXmlFile>testng.xml</suiteXmlFile> <plugin> </suiteXmlFiles> <groupId>org.apache.maven.plugins</groupId> <properties> <artifactId>maven-surefire-plugin</artifactId> <property><version>2.20.1</version> <configuration> <name>reporter</name> <testFailureIgnore>true</testFailureIgnore> <value>org.testng.reporters.XMLReporter:generateTestResultAttributes=true,generateGroupsAttribute=true</value><suiteXmlFiles> </property><suiteXmlFile>testng.xml</suiteXmlFile> </properties>suiteXmlFiles> </configuration> <properties> </plugin> </plugins> </build> <dependencies><property> <dependency> <groupId>org.testng</groupId> <artifactId>testng<<name>reporter</artifactId>name> <version>7.4.0</version> <scope>test</scope> </dependency> <value>org.testng.reporters.XMLReporter:generateTestResultAttributes=true,generateGroupsAttribute=true</value> <dependency> <groupId>com.xpandit.xray</groupId> </property> <artifactId>xray-maven-plugin</artifactId> </properties> <version>1.1.0</version></configuration> <scope>test</scope> </plugin> </dependency>plugins> </dependencies>build> <repositories><dependencies> <repository><dependency> <id>xpandit</id><groupId>org.testng</groupId> <name>xpand-releases</name> <url>http://maven.xpand-it.com/artifactory/releases</url> <artifactId>testng</artifactId> <releases> <enabled>true</enabled> </releases> <version>7.4.0</version> </repository> <<scope>test</repositories>scope> <reporting> <plugins></dependency> <dependency> <plugin> <groupId>app.getxray</groupId> <artifactId>maven<artifactId>xray-surefiretestng-report-plugin<extensions</artifactId> <version>0.1.0</version> </plugin> <scope>test</scope> <plugin> </dependency> </dependencies> <reporting> <groupId>com.xpandit.xray</groupId> <plugins> <artifactId>xray-maven-plugin</artifactId><plugin> <version>1.1.0</version><artifactId>maven-surefire-report-plugin</artifactId> </plugin> </plugins> </reporting> </project> |
...