One of the practice many companies follow is to repeat unstable test until is passes x times (in a row or in total). If it is executed n times and fail to pass at least x times it is marked as failed.
TestNG supports that with the following annotation:
@Test(invocationCount = 5, successPercentage = 40)
How do I realize similar functionality with JUnit5?
There's similar annotation in JUnit5, called @RepeatedTest(5) but it is not executed conditionally.


Ok, I took a little bit of time to whip together a little example of how to do this using the
TestTemplateInvocationContextProvider,ExecutionCondition, andTestExecutionExceptionHandlerextension points.The way I was able to handle failing tests was to mark them as "aborted" rather than let them flat out fail (so that the entire test execution does not consider it a failure) and only fail tests when we can't get the minimum amount of successful runs. If the minimum amount of tests has already succeeded, then we also mark the remaining tests as "disabled". The test failures are tracked in a
ExtensionContext.Storeso that the state can be looked up at each place.This is a very rough example that definitely has a few problems but can hopefully serve as an example of how to compose different annotations. I ended up writing it in Kotlin:
@Retry-esque annotation loosely based on the TestNG example:TestTemplateInvocationContextused by templatized tests:TestTemplateInvocationContextProviderextension for the@Retryannotation:Simple
data classrepresenting the retry (injected into test cases in this example usingParameterResolver).Exceptionused for representing failed retries:Main extension implementing
ExecutionCondition,ParameterResolver, andTestExecutionExceptionHandler.And then, the test consumer:
And the test output in IntelliJ looks like:
I don't know if throwing a
TestAbortedExceptionfrom theTestExecutionExceptionHandler.handleTestExecutionExceptionis supposed to abort the test, but I am using it here.