Page History
...
In this tutorial, we will create aJava a Java Test class with multiple Test Cases, implemented in Java.
The tutorial shows two different approaches for providing additional meta-information for each Test method, one of them will require developing specific code for extending TestNG.
Note that providing additional information on the Test results is optional.
Description
The test case validates automated tests validate a Calculator class and exploits some TestNG features such as the ability of validating the same Test against multiple input values, and also the possibility of linking Tests with requirements in Jira using attributes on the test results, amongst other things.
...
Example 1: Using TestNG standard capabilities
This examples example uses the standard built-in TestNG capabilities, without making use of TestNG's advanced features such as annotations (which in turn would require specific code to handle them).
...
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 com.xpand.annotations.Xray; 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") public void CanAddNumbersFromGivenData(final int a, final int b, final int c) { Assert.assertEquals(Calculator.Add(a, b), c); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("requirement", "CALC-1234"); result.setAttribute("test", "CALC-2"); } @Test public void CanAddNumbers() { Assert.assertEquals(Calculator.Add(1, 1),2); Assert.assertEquals(Calculator.Add(-1, 1),0); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("requirement", "CALC-1234"); result.setAttribute("test", "CALC-2"); result.setAttribute("labels", "core addition"); } @Test public void CanSubtract() { Assert.assertEquals(Calculator.Subtract(1, 1), 0); Assert.assertEquals(Calculator.Subtract(-1, -1), 0); Assert.assertEquals(Calculator.Subtract(100, 5), 95); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("requirement", "CALC-1235"); result.setAttribute("labels", "core"); } @Test public void CanMultiplyX() { Assert.assertEquals(Calculator.Multiply(1, 1), 1); Assert.assertEquals(Calculator.Multiply(-1, -1), 1); Assert.assertEquals(Calculator.Multiply(100, 5), 500); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("requirement", "CALC-1236"); } @Test public void CanDivide() { Assert.assertEquals(Calculator.Divide(1, 1), 1); Assert.assertEquals(Calculator.Divide(-1, -1), 1); Assert.assertEquals(Calculator.Divide(100, 5), 20); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("requirement", "CALC-1237"); } @Test public void CanDoStuff() { Assert.assertNotEquals(true, true); ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute("test", "CALC-6") } } |
Example 2: Using TestNG annotation capabilities
...
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 com.xpand.annotations.Xray;
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(requirement = "CALC-1234", test = "CALC-1")
public void CanAddNumbersFromGivenData(final int a, final int b, final int c)
{
Assert.assertEquals(Calculator.Add(a, b), c);
}
@Test
@Xray(requirement = "CALC-1234", test = "CALC-2", labels = "core addition")
public void CanAddNumbers()
{
Assert.assertEquals(Calculator.Add(1, 1),2);
Assert.assertEquals(Calculator.Add(-1, 1),0);
}
@Test
@Xray(requirement = "CALC-1235", labels = "core")
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 = "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 = "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
@Xray(test = "CALC-6")
public void CanDoStuff()
{
Assert.assertNotEquals(true, true);
}
} |
...
This requires some additional side code, that uses TestNG extension mechanisms, in order to process the custom "Xray" annotation shows shown above. This code is not part of Xray and is only provided for reference; feel free to adapt and customize it to your needs.
...
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; /** * The 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 { String requirement = null; String test = null; String labels = null; 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) ) { testResult.setAttribute("requirement", requirement); method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).requirement()); testResult.setAttribute("test", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).test()); testResult.setAttribute("labels", method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(Xray.class).labels()); } } private boolean annotationPresent(IInvokedMethod method, Class clazz) { boolean retVal = method.getTestMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(clazz) ? true : false; return retVal; } /* (non-Javadoc) * @see org.testng.IInvokedMethodListener#afterInvocation(org.testng.IInvokedMethod, org.testng.ITestResult) */ public void afterInvocation(IInvokedMethod method, ITestResult testResult) { if(method.isTestMethod()) { if( !testSuccess ) { testResult.setStatus(ITestResult.FAILURE); } } } public void onTestStart(ITestResult result) { // TODO Auto-generated method stub } public void onTestSuccess(ITestResult result) { // TODO Auto-generated method stub } public void onTestFailure(ITestResult result) { // TODO Auto-generated method stub } public void onTestSkipped(ITestResult result) { // TODO Auto-generated method stub } public void onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub } public void onStart(ITestContext context) { for(ITestNGMethod m1 : context.getAllTestMethods()) { if(m1.getConstructorOrMethod().getMethod().isAnnotationPresent(Xray.class)) { //capture metadata information. requirement = m1.getConstructorOrMethod().getMethod().getAnnotation(Xray.class).requirement(); test = m1.getConstructorOrMethod().getMethod().getAnnotation(Xray.class).test(); method stub } labelspublic =void m1.getConstructorOrMethod().getMethod().getAnnotation(Xray.class).labels();onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub } public void onStart(ITestContext context) }{ } public void onFinish(ITestContext context) { // TODO Auto-generated method stub } } |
...
After successfully running the tests and generating the TestNG XML report (e.g., ??. testng-results.xml), it can be imported to Xray (either by the REST API or through the Import Execution Results action within the Test Execution).
...