extentreports-java icon indicating copy to clipboard operation
extentreports-java copied to clipboard

CreateTest when called with same TestName does not create another test with same name.

Open yogitthakral opened this issue 6 years ago • 6 comments

I have implemented extent report 3.1.5 via ITestListener interface and using retryAnalyzer in my testsuite.

  1. So , in onStart() method , I have called extent.createTest(String testname) method with testname as argument.
  2. I am printing logs via a common generic file having common methods like click, sendkeys etc. used across @beforemethod @test and @AfterMethod annotations.
  3. Now whenever test case is failed , it goes to retry analyzer and its started again based on retry count.
  4. Again code flow comes to onStart() method of ITestListener Interface which is having extent.create(String testname) method.
  5. Now while retrying the test case since test case name is same , new test case is not created , which is causing logs of the retried test case to be merged with the previous test run logs.

I hope ,I am able to explain the situation , please help me to get over it , Am I missing something here or doing it the wrong way ?

Thanks, Yogit Thakral

yogitthakral avatar Sep 06 '18 18:09 yogitthakral

Can you share the iTestListener code?

anshooarora avatar Sep 06 '18 18:09 anshooarora

Yes Sure ..

yogitthakral avatar Sep 06 '18 19:09 yogitthakral

public class CustomListener extends BaseTestClass implements ITestListener {

public static ExtentReports extent = ExtentManager.getExtent();
public static ThreadLocal<ExtentTest> parentTest = new ThreadLocal<ExtentTest>();
public static ThreadLocal<ExtentTest> test = new ThreadLocal<ExtentTest>();

@Override
public synchronized void onStart(ITestContext context) {
	
	
	
	ExtentTest parent;	
	int arrLength=context.getName().split("\\.").length;
	String testName=context.getName().split("\\.")[arrLength-1];

/just to ignore a specific test from adding to the report/

	if(!testName.equalsIgnoreCase("SetBrowserConfig")){

			if(arrLength>0){
				parent = extent.createTest(testName);
				parent.assignCategory(context.getName().split("\\.")[arrLength-2]);
				test.set(parent);

			}else{
				parent = extent.createTest(context.getName());
				test.set(parent);
			}


		}

	
}



@Override
public synchronized void onFinish(ITestContext context) {
	extent.flush();

}

@Override
public synchronized void onTestStart(ITestResult result) {




}

@Override
public synchronized void onTestSuccess(ITestResult result) {
	if(!result.getMethod().getMethodName().equals("SetBrowserConfig")){
		test.get().pass(result.getMethod().getMethodName()+" passed");
	}

}

@Override
public synchronized void onTestSkipped(ITestResult result) {
if(!result.getMethod().getMethodName().equals("SetBrowserConfig")){
		test.get().skip(result.getMethod().getMethodName()+" skipped");
	}
}



@Override
	public synchronized void onTestFailure(ITestResult result) {
	if(!result.getMethod().getMethodName().equals("SetBrowserConfig")){
		test.get().fail(result.getMethod().getMethodName()+" failed");
	}
	}

@Override public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult result) {

}

yogitthakral avatar Sep 06 '18 19:09 yogitthakral

@yogitthakral can you please format your code so it's readable?

foursyth avatar Sep 06 '18 19:09 foursyth

Please try with this:

public class ExtentITestListener
    implements ITestListener {

    private static final ExtentReports EXTENT = Extent.getInstance();

    private static ThreadLocal<ExtentTest> methodTest = new ThreadLocal<ExtentTest>();
    private static ThreadLocal<ExtentTest> dataProviderTest = new ThreadLocal<>();

    @Override
    public synchronized void onStart(ITestContext context) { }

    @Override
    public synchronized void onFinish(ITestContext context) {
        EXTENT.flush();
    }

    @Override
    public synchronized void onTestStart(ITestResult result) {      
        String methodName = result.getMethod().getMethodName();
        if (result.getParameters().length>0) {
            if (methodTest.get() != null && methodTest.get().getModel().getName().equals(methodName)) { } 
            else {
                createTest(result);
            }
            String paramName = Arrays.asList(result.getParameters()).toString();
            ExtentTest paramTest = methodTest.get().createNode(paramName);
            dataProviderTest.set(paramTest);
        } else {
            createTest(result);
        }
    }

    private void createTest(ITestResult result) {
        String methodName = result.getMethod().getMethodName();
        ExtentTest test = EXTENT.createTest(methodName);
        methodTest.set(test);

        String[] groups = result.getMethod().getGroups();
        if (groups.length > 0) {
            Arrays.asList(groups)
                .forEach(x -> methodTest.get().assignCategory(x));
        }
    }

    @Override
    public synchronized void onTestSuccess(ITestResult result) {
        getTest(result).pass("Test passed");
    }

    private ExtentTest getTest(ITestResult result) {
        ExtentTest t = result.getParameters() != null && result.getParameters().length>0
                ? dataProviderTest.get()
                : methodTest.get();
        return t;
    }

    @Override
    public synchronized void onTestFailure(ITestResult result) {
        getTest(result).fail(result.getThrowable());
    }

    @Override
    public synchronized void onTestSkipped(ITestResult result) {
        getTest(result).skip(result.getThrowable());
    }

    @Override
    public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult result) { }

}

foursyth avatar Sep 06 '18 19:09 foursyth

Thank you so much for helping me out here

Pardon me for code formatting ...

I already tried a similar approach by placing a suffix to retried test case as "retry{counterOfRetry} and it solved the problem with test cases under retry now being entered separately.Well, the problem with this approach is , when you create an extent test on OnTestStart() method and flush it in OnFinish() --- When retry happens , it will start the process again , @beforemethod will be called and the logs created by @beforemethod will be appended to the previous run of the test case since Thread is having the extent test instance of the previous test case.

What I mean to say , is After Flushing and before creating another test case , if thread is having any logs , its writing to the previous test case .

yogitthakral avatar Sep 06 '18 20:09 yogitthakral