How to Rerun Failed Tests with JUnit?

Sometimes due to some temporary problems such as connection problems, server problems, browser issues, mobile application crashes and freezes, and so on our tests fail. In these kinds of situations, we may want to rerun our tests automatically.

But how? We can handle this with test frameworks such as TestNG and JUnit and in this post, I want to show you how to rerun failed tests with JUnit 4.

Also, you can do the same operation with TestNG. It is a great test framework and actually more QA-friendly. In another post, I will also explain how to do the same operation with TestNG using several ways. Especially, you can handle many situations with TestNG Listeners and this is another post topic. Rerun Tests

In my Junit Rules post, I described how to write Custom Rules and I showed a sample custom ScreenShot Rule implementation.  In this post, we will create a similar custom Rule class that implements TestRule class.  We need to override evaluate() method and write retry logic in it.

Rerun Failed Tests with JUnit 4 Example Rerun Tests JUnit

We need two classes, one of them is our Rule Class’s RetryRule and the other is our Test Class’s RetryRuleTest.

In RetryRuleTest class, I will open www.swtestacademy.com and get its title and check it with the WRONG expected title. Thus, our test will fail and I will expect that our test rerun according to the given retry count argument. I set the retry count as 3 in our example.

RetryRule Class

package junit4rerun;

import java.util.Objects;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class RetryRule implements TestRule {
    private int retryCount;

    public RetryRule(int retryCount) {
        this.retryCount = retryCount;
    }

    public Statement apply(Statement base, Description description) {
        return statement(base, description);
    }

    private Statement statement(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                Throwable caughtThrowable = null;
                // implement retry logic here
                for (int i = 0; i < retryCount; i++) {
                    try {
                        base.evaluate();
                        return;
                    }
                    catch (Throwable t) {
                        caughtThrowable = t;
                        System.err.println(description.getDisplayName() + ": run " + (i + 1) + " failed.");
                    }
                }
                System.err.println(description.getDisplayName() + ": Giving up after " + retryCount + " failures.");
                throw Objects.requireNonNull(caughtThrowable);
            }
        };
    }
}

RetryRuleTest Class

package junit4rerun;

import static org.hamcrest.MatcherAssert.assertThat;

import io.github.bonigarcia.wdm.WebDriverManager;
import org.hamcrest.CoreMatchers;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class RetryRuleTest {
    static        WebDriver driver;
    final private String    URL = "https://www.swtestacademy.com";

    @BeforeClass
    public static void setupTest() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
    }

    //Set retry count argument
    @Rule
    public RetryRule retryRule = new RetryRule(3);

    @Test
    public void getURLExample() {
        driver.get(URL);
        assertThat(driver.getTitle(), CoreMatchers.is("WRONG TITLE"));
    }
}

Results

junit rerun

GitHub Project

https://github.com/swtestacademy/selenium-examples/tree/main/src/test/java/junit4rerun

Thanks.
Onur Baskirt

11 thoughts on “How to Rerun Failed Tests with JUnit?”

  1. Thank you very much for this instructive explanation.
    If I may, you’re confusing trying and retrying : a retryCount of 3 means 4 counts in total.

    Reply
  2. Will the retry also reapply other rules to the retried tests, if there are any? So if we have some FirstRule applied to the test, and RetryRule reruns the test, would FirstRule be reapplied during the rerun?

    Reply
  3. Hi Onur,

    I am implementing the code for Cucumber , Could you please let me know how I can use above w.r.t to integrate in Cucucmber

    Reply
  4. Hi Onur,
    I have a question, Currently what is happening failed test cases are running irrespective of category of error message. can I rerun a failed test cases at a particular error message ? Please advise. Thank you in advance

    Reply
    • Hi Shriram,

      I think before below code, there should be some if condition needed to do your requirement. If I have time, I will try to do an example. I am not sure that we can get error message from description field. You can check this for example. I need to open the project and play with it but I did not have time to do.

      // implement retry logic here
      for (int i = 0; i < retryCount; i++) . . . Also, you can check examples here: https://www.swtestacademy.com/junit-5-how-to-repeat-failed-test/

      Check below part in that article. I hope this will help.

      @RepeatedIfExceptionsTest(repeats = 5, exceptions = IOException.class)

      This annotation reruns your test five times if the test fails. Set IOException.class that will be handled in test @throws IOException – error occurred.

      @RepeatedIfExceptionsTest(repeats = 6, exceptions = IOException.class,
      name = “Retry failed test. Attempt {currentRepetition} of {totalRepetitions}”)

      This annotation repeats your test 6 times when it fails. You can also set a custom name. Set IOException.class that will be handled in the test. Set formatter for the test. Like behavior as at {@link org.junit.jupiter.api.RepeatedTest} @throws IOException – error occurred

      Reply
  5. Hi Onur,
    Nice way to re-run failed scenario rather than creating 2runner files but I need to implement in my cucumber junit framework. I am not getting how to do this 😔
    Could you pls help me 🙏 hope you see my msg and help me

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.