'TestNG retry class doesn't run @BeforeClass nor @AfterClass methods

I have a test like this:

public class Test1 extends AbstractTest {

    @Test(retryAnalyzer=Retry.class)
    public void test(){
        System.out.println(this.getClass().getName() + " running.");
        Assert.fail();
    }

}

With setup and teardown methods like this:

public class AbstractTest {

    @BeforeClass(alwaysRun = true)
    public void setup() {
        System.out.println(this.getClass().getName() + " initialized");
    }

    @AfterClass(alwaysRun = true)
    public void tearDown(){
        System.out.println(this.getClass().getName() + " complete");
    }

}

And a retry class like this:

public class Retry implements IRetryAnalyzer {

    private int retryCount = 0;
    private int maxRetryCount = 1;

    public boolean retry(ITestResult result) {
        if (retryCount < maxRetryCount) {
            retryCount++;
            return true;
        }
        return false;
    }

}

But the setup and tearDown methods don't run before and after the test method despite having set alwaysRun to true. Here's some console output:

tests.Test1 initialized
tests.Test1 running.
tests.Test1 running.
tests.Test1 complete

Why is this? How can I get them to run each time the test retries?



Solution 1:[1]

The annotations org.testng.annotations.BeforeMethod and org.testng.annotations.AfterMethod will behave as you require - in other words, run the setup and tear down code before each invocation of the test method, regardless of whether or not it was triggered by a retry.

Full documentation in the TestNG javadoc for @BeforeMethod and @AfterMethod.

Solution 2:[2]

This behaviour is as per design.

@BeforeClass: The annotated method will be run before the first test method in the current class is invoked.

  • In your case it is setup, it will print initialized.
  • setup will never run again until the same class is reloaded for execution.

@AfterClass: The annotated method will be run after all the test methods in the current class have been run.

  • In your case it is tearDown, it will run after all the test methods including all retry attempts in the current class have been run and print complete.

Note: retry(ITestResult result) returns true if the test method has to be retried, false otherwise. So whether test methods have to be retried or not will be governed by the retry method. Behaviour of @BeforeClass and @AfterClass remains unchanged.

Hope this clarifies.

Solution 3:[3]

As of now TestNG doesnot support retry of Configuration methods (e.g beforeMethod , beforeTest etc.. ) https://github.com/cbeust/testng/issues/1444

if configuration method fails tests will skip/fail .

you can use some logic to retry your code inside @BeforeMethod or @BeforeTest ..

int count = 0;
int maxTries = 3;

@BeforeMethod
public void beforeMethod(){
while(true) {
try {
// Some Code
// break out of loop, or return, on success
} catch (SomeException e) {
// handle exception
if (++count == maxTries) throw e;
}
}
}

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 Stephen Hartley
Solution 2 Stephen Hartley
Solution 3 MD AFSAR ALI