Code Monkey home page Code Monkey logo

rerunner-jupiter's Introduction

rerunner-jupiter

Maven Central Build Status badge-jdk-8 License badge

rerunner-jupiter is a extension for Junit 5. Re-run failed JUnit-Jupiter tests immediately. Very useful when your UI/API tests don't stable. This library is open source, released under the terms of [Apache 2.0 License].

How To Use

In order to include rerunner-jupiter in a Maven project, first add the following dependency to your pom.xml (Java 8 required):

<dependency>
    <groupId>io.github.artsok</groupId>
    <artifactId>rerunner-jupiter</artifactId>
    <version>2.1.6</version>
    <scope>test</scope>
</dependency>

Examples

           /** 
            * Repeated three times if test failed.
            * By default Exception.class will be handled in test
            */
           @RepeatedIfExceptionsTest(repeats = 3)
           void reRunTest() throws IOException {
               throw new IOException("Error in Test");
           }
       
       
           /**
            * Repeated two times if test failed. Set IOException.class that will be handled in test
            * @throws IOException - error occurred
            */
           @RepeatedIfExceptionsTest(repeats = 2, exceptions = IOException.class)
           void reRunTest2() throws IOException {
               throw new IOException("Exception in I/O operation");
           }
       
       
           /**
            * Repeated ten times if test failed. Set IOException.class that will be handled in test
            * Set formatter for test. Like behavior as at {@link org.junit.jupiter.api.RepeatedTest}
            * @throws IOException - error occurred
            */
           @RepeatedIfExceptionsTest(repeats = 10, exceptions = IOException.class, 
           name = "Rerun failed test. Attempt {currentRepetition} of {totalRepetitions}")
           void reRunTest3() throws IOException {
                throw new IOException("Exception in I/O operation");
           }
           
           /**
           *  Repeated three times if selenium test failed. Use selenium-jupiter extension.
           */
           @RepeatedIfExceptionsTest(repeats = 3, exceptions = NoSuchElementException.class)
           void testWithChrome(ChromeDriver chrome)  {
                chrome.get("http://yandex.ru");
                chrome.findElement(By.xpath("//span[@id='authors']"));
           }
           
           /**
           * Repeated 100 times with minimum success four times, then disabled all remaining repeats.
           * See image below how it works. Default exception is Exception.class
           */
           @DisplayName("Test Case Name")
           @RepeatedIfExceptionsTest(repeats = 100, minSuccess = 4)
           void reRunTest4() {
                if(random.nextInt() % 2 == 0) {
                    throw new RuntimeException("Error in Test");
                }
           }        
           
          /**
           * By default total repeats = 1 and minimum success = 1.
           * If the test failed by this way start to repeat it by one time with one minimum success.
           *
           * This example without exceptions.
           */
          @ParameterizedRepeatedIfExceptionsTest
          @ValueSource(ints = {14, 15, 100, -10})
          void successfulParameterizedTest(int argument) {
              System.out.println(argument);
          }
      
          /**
           * By default total repeats = 1 and minimum success = 1.
           * If the test failed by this way start to repeat it by one time with one minimum success.
           * This example with display name but without exceptions
           */
          @DisplayName("Example of parameterized repeated without exception")
          @ParameterizedRepeatedIfExceptionsTest
          @ValueSource(ints = {1, 2, 3, 1001})
          void successfulParameterizedTestWithDisplayName(int argument) {
              System.out.println(argument);
          }
      
          /**
           * By default total repeats = 1 and minimum success = 1.
           * If the test failed by this way start to repeat it by one time with one minimum success.
           *
           * This example with display name but with exception. Exception depends on random number generation.
           */
          @DisplayName("Example of parameterized repeated with exception")
          @ParameterizedRepeatedIfExceptionsTest
          @ValueSource(strings = {"Hi", "Hello", "Bonjour", "Privet"})
          void errorParameterizedTestWithDisplayName(String argument) {
              if (random.nextInt() % 2 == 0) {
                  throw new RuntimeException("Exception " + argument);
              }
          }
      
          /**
           * By default total repeats = 1 and minimum success = 1.
           * If the test failed by this way start to repeat it by one time with one minimum success.
           *
           * This example with display name, repeated display name, 10 repeats and 2 minimum success with exceptions.
           * Exception depends on random number generation.
           */
          @ParameterizedRepeatedIfExceptionsTest(name = "Argument was {0}",
                  repeatedName = " (Repeat {currentRepetition} of {totalRepetitions})",
                  repeats = 10, exceptions = RuntimeException.class, minSuccess = 2)
          @ValueSource(ints = {4, 5, 6, 7})
          void errorParameterizedTestWithDisplayNameAndRepeatedName(int argument) {
              if (random.nextInt() % 2 == 0) {
                  throw new RuntimeException("Exception in Test " + argument);
              }
          }
      
          /**
           * By default total repeats = 1 and minimum success = 1.
           * If the test failed by this way start to repeat it by one time with one minimum success.
           *
           * This example with display name, implicitly repeated display name, 4 repeats and 2 minimum success with exceptions.
           * Exception depends on random number generation. Also use {@link MethodSource}
           */
          @DisplayName("Display name of container")
          @ParameterizedRepeatedIfExceptionsTest(name = "Year {0} is a leap year.",
                  repeats = 4, exceptions = RuntimeException.class, minSuccess = 2)
          @MethodSource("stringIntAndListProvider")
          void errorParameterizedTestWithMultiArgMethodSource(String str, int num, List<String> list)  {
              assertEquals(5, str.length());
              assertTrue(num >= 1 && num <= 2);
              assertEquals(2, list.size());
              if (random.nextInt() % 2 == 0) {
                  throw new RuntimeException("Exception in Test");
              }
          }
      
          static Stream<Arguments> stringIntAndListProvider() {
              return Stream.of(
                      arguments("apple", 1, Arrays.asList("a", "b")),
                      arguments("lemon", 2, Arrays.asList("x", "y"))
              );
          }
          
          
          /**
          *  it's often caused by some infrastructure problems: network congestion, garbage collection etc. 
          *  These problems usually pass after some time. Use suspend option
          */
          @RepeatedIfExceptionsTest(repeats = 3, exceptions = IOException.class, suspend = 5000L)
          void reRunTestWithSuspendOption() throws IOException {
              throw new IOException("Exception in I/O operation");
          }
          
          
           /**
           * Example with suspend option for Parameterized Test
           * It matters, when you get some infrastructure problems and you want to run your tests through timeout.
           *
           * Set break to 5 seconds. If exception appeared for any arguments, repeating extension would runs tests with break.
           * If one result failed and other passed, does not matter we would wait 5 seconds throught each arguments of the repeated tests.
           *
           */
           @DisplayName("Example of parameterized repeated with exception")
           @ParameterizedRepeatedIfExceptionsTest(suspend = 5000L, minSuccess = 2, repeats = 3)
           @ValueSource(strings = {"Hi", "Hello", "Bonjour", "Privet"})
           void errorParameterizedTestWithSuspendOption(String argument) {
                if (random.nextInt() % 2 == 0) {
                    throw new RuntimeException(argument);
                }
           }
           
           /**
           * Parameterized Test with the wrong exception.
           * Test throws AssertionError.class, but we wait for Exception.class.
           * In this case test with argument "1" runs ones without repeats.
           * 
           * If you change 'exceptions = AssertionError.class', repeats will appear.
           */
           @ValueSource(ints = {1, 2})
           @ParameterizedRepeatedIfExceptionsTest(repeats = 2, exceptions = Exception.class)
           void testParameterizedRepeaterAssertionsFailure(int value) {
                assertThat(value, equalTo(2));
           }

More examples you can find here.

GitHub Star

Push to the star if you like this JUnit 5 Extension. By this way, I will get feedback from you!

rerunner-jupiter's People

Contributors

616slayer616 avatar artsok avatar barkavi14 avatar l891211blue avatar meikemertschfortum avatar spanierm42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rerunner-jupiter's Issues

match test as failed ONLY when LAST test-attempt failed

is it possible to update your great code to match test as failed ONLY when LAST test-attempt failed? I mean to throw e.g. abort exception when test is failing during repetition... This way when tests tun at any CI/CD (Jenkins, Bamboo) test suite will mark as Green when repetition passed.

From Roman Hesteric

Null pointer on test error

I just upgraded from 1.1.0 to 2.0.1. I'm using junit 5.4.0 and java 8.

I found that running with the extension causes a NullPointerException. Given the null pointer it seems that the method provideTestTemplateInvocationContexts wasn't called before afterTestExecution.

Would initializing historyExceptionAppear declared fix the issue properly?

java.lang.NullPointerException
	at io.github.artsok.extension.RepeatIfExceptionsCondition.afterTestExecution(RepeatIfExceptionsCondition.java:128)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterTestExecutionCallbacks$8(TestMethodTestDescriptor.java:220)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:245)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:243)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterTestExecutionCallbacks(TestMethodTestDescriptor.java:219)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)

'junit-jupiter' failed to discover tests in Jenkins

Rerunning tests with this extension work fine in my IntelliJ IDEA but fail in Jenkins with following message,

org.junit.platform.launcher.core.DefaultLauncher handleThrowable
WARNING: TestEngine with ID 'junit-jupiter' failed to discover tests
java.lang.NoSuchMethodError: org.junit.platform.engine.support.filter.ClasspathScanningSupport.buildClassFilter(Lorg/junit/platform/engine/EngineDiscoveryRequest;Ljava/util/function/Predicate;)Lorg/junit/platform/commons/util/ClassFilter;
at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:49)
at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:61)
at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:130)
at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:117)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:82)
at org.junit.platform.surefire.provider.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:50)
at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:98)
at org.junit.platform.surefire.provider.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:121)
at org.junit.platform.surefire.provider.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:111)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)

No tests are executed, even the ones without the @RepeatedIfExceptionsTest annotation.

Test class fails if it not found any test case to run in case of @EnabledIfSystemProperty

I've set the System property "os" to "WINDOWS" and then,
I'm running test cases using @Test annotation with the @EnabledIfSystemProperty(named = "os", matches = "LINUX")

@Test
@EnabledIfSystemProperty(named = "os", matches = "LINUX")
void testUserLogin(testContext)
{
}

In this case the entire test suite is marked skipped with the warning,
System property [os] with value [WINDOWS] does not match regular expression [LINUX]

but when i run the same using the @RepeatedIfExceptionsTest(suspend = 3000L) insted of @Test
it shows
Test ignored.

And the test suite class fails with the below exception

org.junit.platform.suite.engine.NoTestsDiscoveredException: Suite [com.mindarray.suite.LDAPServerSuite] did not discover any tests

	at org.junit.platform.suite.engine.SuiteTestDescriptor.computeTestExecutionResult(SuiteTestDescriptor.java:134)
	at org.junit.platform.suite.engine.SuiteTestDescriptor.execute(SuiteTestDescriptor.java:129)
	at org.junit.platform.suite.engine.SuiteTestEngine.lambda$execute$0(SuiteTestEngine.java:73)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at org.junit.platform.suite.engine.SuiteTestEngine.execute(SuiteTestEngine.java:73)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:73)
	at org.junit.platform.suite.engine.SuiteLauncher.execute(SuiteLauncher.java:63)
	at org.junit.platform.suite.engine.SuiteTestDescriptor.execute(SuiteTestDescriptor.java:128)
	at org.junit.platform.suite.engine.SuiteTestEngine.lambda$execute$0(SuiteTestEngine.java:73)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at org.junit.platform.suite.engine.SuiteTestEngine.execute(SuiteTestEngine.java:73)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

Any Solution to this @artsok ?

@ParameterizedRepeatedIfExceptionsTest test status is failed for any repetion

Using the following annotation
@ParameterizedRepeatedIfExceptionsTest (repeats = 4, minSuccess = 1, name = "{0}", repeatedName = "repeat", exceptions = AssertionError.class)

If for one value the test runs 3 times - failure, failed repeat, successfull repeat - this results in 2 failed and one passed test.

I would expect one passed test as for @RepeatedIfExceptionsTest.

MinSuccess is not respected if there was a previous fail

If there is a testfailure in the first runs the test will run times instead of minSuccess is fullfilled.

private int test = 0;

@DisplayName("should stop after 3rd retry, but runs 20 times")
@RepeatedIfExceptionsTest(repeats = 20, suspend = 1000, minSuccess = 1)
public void testTest() {
	if (test < 2) {
		test++;
		fail();
	}
}

One successful @RepeatedIfExceptionTest disables ALL other tests marked with @RepeatedIfExceptionTest

I noticed a significant drop-off in the number of tests being run once I applied the @RepeatedIfExceptionTest annotation to 10 or so of the tests in my project. It seems that all tests marked with the annotation are disabled as soon as one test marked with it has passed.

When

  • I have multiple tests marked with @RepeatedIfExceptionTest
  • and the first test in the suite runs through successfully (no failures, no errors)

the other tests in that suite marked with @RepeatedIfExceptionTest should run.

Instead, the additional tests marked with @RepeatedIfExceptionTest are all immediately skipped. No code within them is run.

This even applies to other test suites when all suites are run through Maven (mvn clean test).

Code to recreate:

import io.github.artsok.RepeatedIfExceptionsTest;
import org.junit.jupiter.api.Test;

public class RepeatTest {
    @RepeatedIfExceptionsTest(repeats = 3, name = "test1")
    public void test1() {
        System.out.println("Test one is running");
    }

    @RepeatedIfExceptionsTest(repeats = 3, name = "test2")
    public void test2() {
        System.out.println("Test two is running");
        throw new RuntimeException("This should error");
    }

    @Test
    public void regularTest() {
        System.out.println("Running regular test");
    }
}

When the above suite is run using Junit 5.2.0, the following is output:

Running regular test
Test one is running

Turn off the remaining tests that must be performed

Process finished with exit code 0

As you can see the code in test2 is never run, and in IntelliJ it is marked as having been skipped.

Unable to instantiate driver for failed test Serenity and Junit 5

I am using serenity with junit5 and Gradle. I am trying to run the failed scenario using the below dependency.

testImplementation group: 'io.github.artsok', name: 'rerunner-jupiter', version: '2.1.6'

But failed to instantiate driver when the test failed in the first attempt.

@RepeatedIfExceptionsTest(repeats = 2, exceptions = Exception.class, name = "Rerun failed test. Attempt {currentRepetition} of {totalRepetitions}", suspend = 15000L).

Is there any way to execute serenity failed cases using junit5?

java.lang.NullPointerException

There is a bug in your repo all tests are running multiple times.
Getting below exception if we are trying run test
image

java.lang.NullPointerException
	at io.github.artsok.extension.RepeatIfExceptionsExtension.afterTestExecution(RepeatIfExceptionsExtension.java:125)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterTestExecutionCallbacks$8(TestMethodTestDescriptor.java:229)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$12(TestMethodTestDescriptor.java:269)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:269)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:268)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterTestExecutionCallbacks(TestMethodTestDescriptor.java:228)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:133)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.executeNonConcurrentTasks(ForkJoinPoolHierarchicalTestExecutorService.java:155)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:129)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1067)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172)

@ParameterizedRepeatedIfExceptionsTest ignores parameter source on assertion failure

The following test will run thrice:

@ValueSource(ints = {1, 2})
@ParameterizedRepeatedIfExceptionsTest(repeats = 2)
 void testParameterizedRepeaterAssertionsFailure(int value) {
    assertThat(value, equalTo(2));
}

each time failing because 1 != 2. The test is never run for value == 2

Tested on Java 8 using version 2.0.1 of rerunner-jupiter library and Gradle 5.4.1.

Meaning of parameter 'repeats' is different in @RepeatedIfExceptionsTest and @ParameterizedRepeatedIfExceptionsTest

The following test will run twice:

@RepeatedIfExceptionsTest(repeats = 2)
void testRepeater() {
    assertThat(1, equalTo(2));
}

and this will run three times:

@ValueSource(ints = {1})
@ParameterizedRepeatedIfExceptionsTest(repeats = 2)
void testParameterizedRepeater(int value) {
     assertThat(value, equalTo(2));
}

even though both have parameter repeats set to 2.

Tested on Java 8 using version 2.0.1 of rerunner-jupiter library and Gradle 5.4.1.

messageRegex and traceRegex?

Would you consider making it possible to repeat if the exception message matches a certain regex or to repeat if the stacktrace matches a certain regex (which would cover caused-by things)?

Because just to repeat on a certain exception type is sometimes not precise enough, it can be too broad, and having no influence on the exception types since they are 3rd party.

Surefire reports count test as having been skipped

When the maven surefire plugin creates test result XML files, each test that was annotated with @RepeatedIfExceptionsTest is marked as having been skipped.

<testcase name="testMethodName" classname="className" time="0"> <skipped message="Turn off the remaining tests that must be performed"/> </testcase>

In reality the tests ran successfully, but the test was disabled when the minimum number of successes was reached.

Is there a way to retain the passed result, rather than having these marked as skipped?

New Maven release including feature #15

Hi @artsok,

Can you please perform a new release to Maven Central with the changes from #15? The pull request was merged a month ago and we would really love to use it in our projects. This would also help with #8.

Thanks a lot and best regards,
Markus

README should mention that ExecutionMode.CONCURRENT is not supported

I think, it is very important to mention in the README, that this library does not work, when using @Execution(ExecutionMode.CONCURRENT).

If you run your tests in parallel, a test annotated with @RepeatedIfExceptionsTest(repeats = 10) is only executed one single time but just marked as skipped. This is very dangerous, because the only job of a test is to fail in certain cases. But with this setup, the test will never cause your build to fail, even if the test would have failed all 10 times.

NullPointerException if RepeatedTest is cancelled

We get an NullPointerException if we abort a test which is annotated with RepeatedIfExceptionsTest. Assume there is an JUnit5 extension to stop further test exectuions if there is some condition (see below). If the condition is met we will get a NPE in RepeatIfExceptionsExtension line 131 because repeatableExceptions is uninitialized.

public void beforeTestExecution(ExtensionContext context) throws Exception {
	if (<some condition to stop further test exectution>) {
		throw new TestAbortedException("Cancel this test");
	}
}

Please remove dependency on slf4j-simple

The dependency on slf4j-simple should be a test dependency, not a compile or runtime dependency. Removing this dependency allows users of rerunner-jupiter to choose which slf4j backend they want to use.

With this dependency in rerunner-jupiter I get the following warnings when running my tests.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/jpschewe/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.26/12f5c685b71c3027fd28bcf90528ec4ec74bf818/slf4j-log4j12-1.7.26.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/jpschewe/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/1.7.5/4a950c50bbc67fdbc908190dc8e25d7a0251f74a/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

Issue with current Jupiter Version

I am developing autmated UI Tests with Appium and I use the current junit-jupiter-api (5.1.1) for the test cases. This also requires selenium-jupiter (2.1.1) to work.

When using the rerunner-jupiter plugin however I receive a NullPointerException which seems to be caused by the DefaultLauchner.java in the junit-platform-launcher:1.0.0 dependency. Does anyone else also observe this behavior and might have a solution or is this caused because of the newer versions of junit-jupiter-api?

java.lang.NullPointerException at java.io.Reader.<init>(Reader.java:78) at java.io.InputStreamReader.<init>(InputStreamReader.java:113) at org.apache.commons.io.IOUtils.copy(IOUtils.java:2440) at org.apache.commons.io.IOUtils.toString(IOUtils.java:1084) at io.github.bonigarcia.SeleniumExtension.provideTestTemplateInvocationContexts(SeleniumExtension.java:334) at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.lambda$execute$0(TestTemplateTestDescriptor.java:97) at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:101) at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:38) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:112) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Iterator.forEachRemaining(Iterator.java:116) at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Iterator.forEachRemaining(Iterator.java:116) at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120) at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Usage with AssertJ possible?

Hi Artem,

nice extension, it works good with JUnit 5 Assertions.
Unfortunately it does not seem to work with JUnit 5 and AssertJ. I configured the RepeatedIfExceptionsTest annotation with
exceptions = Error.class
or
AssertionFailedError
AssertionError

parameter, but each test is only run once.

Make Poll of exceptions to accept Throwables

For now only classes that inherit from java.lang.Exception.class are accepted by RepeatedIfExceptionsTest.extensions() method. This is quite inconvenient as sometimes you want to also rerun test if AssertionError occurs.
This is especially vital if you're working with Selenide library which usually throws com.codeborne.selenide.ex.ElementNotFound exception if element not found which in turn inherits from AssertionError
A minor changes in a code are required for this to be fixed (check this row in a code)

Class<? extends Throwable>[] exceptions() default Exception.class;

Most common Junit assertion failures cannot be retried

The errors that rerunner-jupiter are currently capable of handling all extend from Exception.

This rules out handling for some of most common types of failure situations in tests: Junit's AssertionFailedError.

Can we alter the project so it handles everything that extends from Throwable instead, and make Throwable.class itself the default "exception" to be handled?

That way, by default any test failure will by handled without the need to always specify this behaviour.

stop retry when same exceptions occurred

Hi, thank you for the great feature.

I'd like to stop retry when same exceptions will be occurred with exactly same error-message.
Because I think the flaky tests should retry but the broken tests should not retry.

example 1

@DisplayName("retry should be stop at Repetition 2 of 3")
@RepeatedIfExceptionsTest(repeats = 3,maxExceptions = 2)
public void reRunTestStopRetryIfSameExceptions2() {
    throw new RuntimeException("same error message");
}

example 2

@DisplayName("fail at Repetition 4 of 4(retry will not be stopped)")
@RepeatedIfExceptionsTest(repeats = 4,maxExceptions = 2)
public void reRunTestStopRetryIfSameExceptions3() {
    throw new RuntimeException("dynamic error message: " + random.nextInt());
}

Add optional cooldown for failing test

When tests fails, it's often caused by some infrastructure problems: network congestion, garbage collection etc. These problems usually pass after some time.

It will be nice to have a parameter that can be used to slow down execution in case of failure - say cooldown parameter.

@RepeatedIfExceptionsTest(repeats = 3, minSuccess = 2, cooldown = 2_000L)

HTML report output is empty for all tests that have rerun

On jenkins we use the html report from the tests but for all tests that have failed at least once (and all their reruns) the output is completely empty. Meaning I cannot find out why a run was skipped to improve the granularity of the tests.

Maven tests that are having @RepeatedIfExceptionsTest which are under src/main/java are not getting executed

Hi,
I have my test framework which is a maven project. All the test classes are in /src/main/java, After adding the below in pom.xml, I noticed all the other tests are executed except the ones which are having @RepeatedIfExceptionsTest were not getting executed. If there any workaround we have?

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <testSourceDirectory>${basedir}/src/main/java/</testSourceDirectory>
                <testClassesDirectory>${project.build.directory}/classes/</testClassesDirectory>
                <workingDirectory>${basedir}/src/main/java/</workingDirectory>
</configuration>
        </plugin>

Feature request: Java 9 Support

@artsok correct me if i'm wrong but this extension should not work with java9+junit 5?
I've tried the RepeatedIfExceptionsTest annotation but it seems to run as regular test with no repeat failure.

Concurrent Modification Exception when using with parallel test execution

Test annotated with: @ParameterizedRepeatedIfExceptionsTest
junit-platform.properties: junit.jupiter.execution.parallel.mode.default=concurrent

java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1660)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:257)
	at java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:248)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:605)
	at io.github.artsok.extension.ParameterizedRepeatedExtension.handleTestExecutionException(ParameterizedRepeatedExtension.java:137)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestExecutionExceptionHandlers(TestMethodTestDescriptor.java:210)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestExecutionExceptionHandlers(TestMethodTestDescriptor.java:196)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:188)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:171)
	at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

@ParameterizedRepeatedIfExceptionsTest will enter infinite loop if parameter `exceptions` is set and assertion fails

The following test will run four times, failing three times and then succeeding:

@ValueSource(ints = {1, 2})
@ParameterizedRepeatedIfExceptionsTest(repeats = 2)
 void testParameterizedRepeaterAssertionsFailure(int value) {
    assertThat(value, equalTo(2));
}

The same test with exceptions parameter set will run an infinite number of times, only failing the first time:

@ValueSource(ints = {1, 2})
@ParameterizedRepeatedIfExceptionsTest(repeats = 2, exceptions = Exception.class)
void testParameterizedRepeaterAssertionsFailure(int value) {
    assertThat(value, equalTo(2));
}

Tested on Java 8 using version 2.0.1 of rerunner-jupiter library and Gradle 5.4.1.

PreconditionViolationException

Hello there

I got the below thrown on Jenkins while rerunner-jupiter in pom. maven-surefire-plugin version: 2.22.2

There was an error in the forked process
[ERROR] org/junit/platform/commons/PreconditionViolationException
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] org/junit/platform/commons/PreconditionViolationException
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:656)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
[ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
[ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
[ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.lang.reflect.Method.invoke(Method.java:498)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

Number of retries must be a constant and hardcoded

Currently the number of retries that you want a test to do is passed in through the annotation, this means it must be a constant.

There are cases where different jobs may want to have a different number of retries, for example branch builds may want to retry more because they care more about getting a consistent result.

Rerun failed parametrized tests

Hi
I tried to use @RepeatedIfExceptionsTest for @ParameterizedTest. Unfortunately the failed tests did not rerun? Is it not possible to combine both?

Regards
George

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.