Print Test Result in JUnit - java

Currently I am making the test case repeat 2 times, so how do I print the results as 2 separate results.
I tried using the built-in function to create the text, however, it does now show either "Success" or "Failure".
Currently I have this code:
public class UnitTestRunner {
static JUnitCore junitCore;
static Class<?> testClasses;
public static void main(String[] args) {
System.out.println("Running Junit Test Suite.");
Result result = JUnitCore.runClasses(TestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println("Successful: " + result.wasSuccessful() +
" ran " + result.getRunCount() + " tests");
}
}
This code is working correctly, but I do not know how to implement this into JUnit.
Can someone please help to show, how to implement this code into JUnit test case.

This will be slightly long answer. For the customized output you have to add your RunListener
You can use following sample implementation for the same.
public class UnitTestRunner {
static JUnitCore junitCore;
static Class<?> testClasses;
public static void main(String[] args) {
System.out.println("Running Junit Test Suite.");
junitCore = new JUnitCore();
junitCore.addListener(new CustomExecutionListener());
Result result = junitCore.run(TestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println("Successful: " + result.wasSuccessful() + " ran " + result.getRunCount() + " tests");
}
}
And implementation for the RunListener is as follows
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
public class CustomExecutionListener extends RunListener {
public void testRunStarted(Description description) throws Exception {
System.out.println("Number of tests to execute: " + description.testCount());
}
public void testRunFinished(Result result) throws Exception {
System.out.println("Number of tests executed: " + result.getRunCount());
}
public void testStarted(Description description) throws Exception {
System.out.println("Starting: " + description.getMethodName());
}
public void testFinished(Description description) throws Exception {
System.out.println("Finished: " + description.getMethodName());
}
public void testFailure(Failure failure) throws Exception {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
public void testAssumptionFailure(Failure failure) {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
public void testIgnored(Description description) throws Exception {
System.out.println("Ignored: " + description.getMethodName());
}
}
And by overriding the methods in RunListener you can format you output.

Related

Screenshot isn't attached to allure results folder and in the allure report

Screenshot isn't attached to allure results folder and in the allure report. I don't understand what's the problem. Have tried to add listeners in testng.xml and in the test class above the test name - no difference-> the png file isn't shown in the allure results when the test is failed. What am I doing wrong?
public class AllureReportListener implements ITestListener {
#Attachment(value = "Page screenshot", type = "image/png")
public byte[] saveScreenshotPNG (WebDriver driver) {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
#Override
public void onStart(ITestContext iTestContext) {
System.out.println("Starting Test Suite '" + iTestContext.getName() + "'.......");
iTestContext.setAttribute("WebDriver", BaseTest.getDriver());
}
#Override
public void onFinish(ITestContext iTestContext) {
System.out.println("Finished Test Suite '" + iTestContext.getName() + "'");
}
#Override
public void onTestStart(ITestResult iTestResult) {
System.out.println("Starting Test Method '" + getTestMethodName(iTestResult) + "'");
}
#Override
public void onTestSuccess(ITestResult iTestResult) {
System.out.println("Test Method '" + getTestMethodName(iTestResult) + "' is Passed");
}
#Override
public void onTestFailure(ITestResult iTestResult) {
System.out.println("Test Method '" + getTestMethodName(iTestResult) + "' is Failed");
if (BaseTest.getDriver() != null) {
System.out.println("Screenshot has captured for the Test Method '" + getTestMethodName(iTestResult) + "'");
saveScreenshotPNG(BaseTest.getDriver());
}
}
#Override
public void onTestSkipped(ITestResult iTestResult) {
System.out.println("Test Method '" + getTestMethodName(iTestResult) + "' is Skipped");
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) {
}
private static String getTestMethodName(ITestResult iTestResult) {
return iTestResult.getMethod().getConstructorOrMethod().getName();
}
}

Skipped test is not logged as Skipped in ExtentReport4

I got 2 tests: addNewVideo and deleteRecentVideo where the second one depends on first one. After first fails, second gets ignored and it's not running. After opening my Extent Report, it looks like this:
I'm expecting to have 2 tests - 1 failed, 1 skipped, but it's not showing properly on the report.
ExtentListener.class
import com.aventstack.extentreports.*;
import com.aventstack.extentreports.markuputils.*;
import org.testng.*;
import java.util.*;
import static constants.FileResources.REPORT_DIR;
public class ExtentListener implements ITestListener {
private static Date d = new Date();
private static String fileName = String.format("%s%s%s%s", d.toString().replaceAll("[: ]", "_"), "_", System.getenv("env"), ".html");
private static ExtentReports extent = ExtentManager.createInstance(REPORT_DIR + fileName);
public static ThreadLocal<ExtentTest> testReport = new ThreadLocal<>();
#Override
public void onTestStart(ITestResult result) {
ExtentTest test = extent.createTest(result.getTestClass().getName() + "." + result.getMethod().getMethodName());
test.assignCategory(result.getTestClass().getName());
testReport.set(test);
}
#Override
public void onTestSuccess(ITestResult result) {
String methodName = result.getMethod().getMethodName();
String logText = methodName + " PASSED";
Markup m = MarkupHelper.createLabel(logText, ExtentColor.GREEN);
testReport.get().pass(m);
}
#Override
public void onTestFailure(ITestResult result) {
String methodName = result.getMethod().getMethodName();
String excepionMessage = Arrays.toString(result.getThrowable().getStackTrace());
testReport.get().fail("<details>" + "<summary>" + "<b>" + "<font color=" + "red>" + "Exception occured: Expand to check details"
+ "</font>" + "</b >" + "</summary>" + excepionMessage.replaceAll(",", "<br>") + "</details>" + " \n");
String failureLog = methodName + " FAILED";
Markup m = MarkupHelper.createLabel(failureLog, ExtentColor.RED);
testReport.get().log(Status.FAIL, m);
}
#Override
public void onTestSkipped(ITestResult result) {
String methodName = result.getMethod().getMethodName();
String logText = "<b>" + methodName + " SKIPPED" + "</b>";
Markup m = MarkupHelper.createLabel(logText, ExtentColor.ORANGE);
testReport.get().skip(m);
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
}
#Override
public void onStart(ITestContext context) {
}
#Override
public void onFinish(ITestContext context) {
if (extent != null) {
extent.flush();
}
}
}
I've tried implementing IInvokedMethodListener but no success.
Is there any way to show skipped tests properly on ExtentReport4?
Guys I also faced this issue and below code worked for me.
Define the testListener like this and then call this testListener class in your Baseclass by using #listeners(TestListeners.class) before Baseclass starts.
Note : I have used Spark Extentreport
public class TestListeners implements ITestListener {
#override
public void onTestSkipped(ITestResult result) {
Baseclass.extenttest = Baseclass.extent.createTest(result.getMethod().getDescription()).assignCategory("SkipedTest");
Baseclass.extenttest .log(Status.SKIP, result.getThrowable());
Baseclass.extenttest .log(Status.SKIP, result.getMethod().getDescription());
Baseclass.extenttest .log(Status.SKIP, MarkupHelper.createLabel(result.getName(), ExtentColor.YELLOW));
Baseclass.extent.flush();
}
}
In your test class define #Test like below
#Test(description = "Test Case name", dependsOnMethods = { "Name of method on which it depends" })
I tried IInvokeMethodListener2 once again, but it's just a workaround.
If method from dependsOnMethods failed, the test method was not executed at all, therefore it was not logged as skipped. My solution is to tag dependant methods as description and check before invocation if it contains any failed method from test class.
public class MethodListener implements IInvokedMethodListener2 {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult, ITestContext context) {
List<String> failed = context
.getFailedTests()
.getAllMethods()
.stream()
.map(ITestNGMethod::getMethodName)
.collect(Collectors.toList());
boolean isSkippable = false;
if (failed.size() > 0 && method.getTestMethod().getDescription() != null) {
List<String> methodNames = Arrays.asList(method.getTestMethod().getDescription().split(";"));
isSkippable = failed
.stream()
.anyMatch(methodNames::contains);
}
if (isSkippable) {
throw new SkipException("Skipping " + method.getTestMethod().getMethodName());
}
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult, ITestContext context) {
}
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
}
}
#Listeners({MethodListener.class, ExtentListener.class})
public class SampleTest extends TestsBase {
#Test(priority = 1)
public void pass() {
System.out.println("pass");
}
#Test(priority = 2)
public void fail1() {
System.out.println("fail1");
Assert.fail();
}
#Test(priority = 3)
public void fail2() {
System.out.println("fail2");
Assert.fail();
}
#Test(priority = 4)
public void fail3() {
System.out.println("fail3");
Assert.fail();
}
#Test(priority = 5)
public void fail4() {
System.out.println("fail4");
Assert.fail();
}
#Test(priority = 6, description = "pass;fail2")
public void skip1() {
System.out.println("skip1");
}
#Test(priority = 7, description = "pass;fail3")
public void skip2() {
System.out.println("skip2");
}
}

Sync between error Listener and Test execution in WebDriver

I am trying to implement a javaScript error listener on the Selenium tests built in my Java project.
In order to detect console Java Script errors, I implemented a script in the JavaScript project which will push the console error messages at the bottom of the body, with a certain element containing a specific ID and the error message.
The error Listener I coded looks like:
public class ErrorListener implements Runnable{
WebDriver driver = null;
public ErrorListener (WebDriver driver)
{
this.driver = driver;
}
private void Listen ()
{
try
{
while(!driver.toString().contains("null")) //Chrome is alive
{
List<WebElement> list = driver.findElements(By.xpath("//div[#id='jsError']"));
if(list.size() != 0)
{
WebElement Error = list.get(0);
String ErrorMSG = Error.getText();
if(ErrorMSG != null)
{
Reporter.log("Found a javascript error with code: "+ErrorMSG);
Assert.assertTrue(false); // force the test failure
}
}
}
}catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void run()
{
Listen();
}
}
Which I am calling in my test method such as:
public class TC_NewAccount
{
public WebDriver driver;
public Thread listener;
#BeforeMethod
public void beforeTest()
{
Reporter.log("The test has just begun.");
driver = NewChrome.Generate(true);
ErrorListener errorlog = new ErrorListener(driver);
listener = new Thread(errorlog);
listener.start();
}
#AfterMethod
public void afterClass()
{
Reporter.log("Test has now finished.");
driver.close();
}
#DataProvider
public static Object[][] credentials()
{
return new Object[][] { { "id", "password" }};
}
#Test(dataProvider = "credentials")
public void Execute(String username, String password) throws Exception
{
... whatever the test does
}
}
The problem is, that since I am using the same instance of Chrome to constantly listen to a specific WebElement, I am throwing requests in parallel from both methods (the test and the listener), and the process ends up crashing because of them being at the same time and not being synced (one after another).
I realised that one option could be to check for errors after I do certain action every time, but this would greatly increment my lines of code, and it is only a partial solution because some errors may occur just in terms of milliseconds...
Is there a smooth solution for this problem?
Thanks in advance!
first of all you have to create you TestListener.java file
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
#Override
public void onTestStart(ITestResult result) {
System.out.println("Started Test: " + result.getName());
}
#Override
public void onTestSuccess(ITestResult result) {
System.out.println("Finished Test: " + result.getName() + " :PASSED");
}
#Override
public void onTestFailure(ITestResult result) {
System.out.println("Finished Test: " + result.getName() + " :FAILED");
}
#Override
public void onTestSkipped(ITestResult result) {
System.out.println("Finished Test: " + result.getName() + " :SKIPPED");
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
System.out.println("Finished Test: " + result.getName()
+ " :FAILED BUT WITHIN SUCCESS PERCENTAGE");
}
#Override
public void onStart(ITestContext context) {
// TODO Auto-generated method stub
}
#Override
public void onFinish(ITestContext context) {
// TODO Auto-generated method stub
}
}
you can customize this file according to you . Next what you have to do is you need to mention this listener in your Test class
#Listeners(TestListener.class)
public class TestClass{
#Test(dataProvider = "TestData" , dataProviderClass = DataProviderUtil.class)
public void test(List data) throws Exception {
try{
// your code here
}
catch(Exception e){
Log.exception(e);
}finally {
Log.endTestCase();
}
}
}

JUnit get tests results at AfterClass

I need to run tests classes and show the results in screen, following this structure, but just after running all.
#RunWith(Suite.class)
#Suite.SuiteClasses({
LoginTest.class,
LogoutTest.class
})
public class AllTests {
protected static WebDriver driver;
#BeforeClass
public static void beforeClass() throws Exception {
driver = Selenium.getDriver();
driver.navigate().to(Property.SITE_ADDRESS);
driver.manage().window().maximize();
}
#AfterClass
public static void afterClass() throws Exception {
String resultString = "";
Result result = JUnitCore.runClasses(AllTests.class);
for (Failure fail : result.getFailures()) {
resultString += result.getClass() +": "+ fail.toString()+"\n";
}
if (result.wasSuccessful()) {
resultString += result.getClass() +": "+ result + "\n";
}
JFrame frame = new JFrame("Results");
JOptionPane.showMessageDialog(frame, resultString, "Title", JOptionPane.INFORMATION_MESSAGE);
driver.quit();
}
My #AfterClass is re-running my test classes, is there any other solution?

How to retry the entire test class in TestNG?

I have a test case like this:
#Listeners({RetryListener.class})
public class TestClass {
#Test
public void test1() throws Exception {
//something
}
#Test(dependsOnMethods = "test1")
public void test2() throws Exception {
//something
}
#Test(dependsOnMethods = "test2")
public void test3() throws Exception {
//something
}
}
As you can see, there are dependencies on the tests. I would like to retry the entire test class once there is anything wrong with the tests.
Is there a way to do it in TestNG?
My RetryListener looks like this:
public class RetryListener extends TestListenerAdapter {
private int count = 0;
#Override
public void onTestFailure(ITestResult result) {
if (result.getMethod().getRetryAnalyzer() != null) {
Reporter.setCurrentTestResult(result);
if(result.getMethod().getRetryAnalyzer().retry(result)) {
count++;
result.setStatus(ITestResult.SKIP);
System.out.println("Error in " + result.getName() + " with status "
+ result.getStatus()+ " Retrying " + count + " of 3 times");
System.out.println("Setting test run attempt status to Skipped");
} else {
count = 0;
System.out.println("Retry limit exceeded for " + result.getName());
}
Reporter.setCurrentTestResult(null);
}
}
#Override
public void onTestSuccess(ITestResult result) {
count = 0;
}
}

Categories