diff --git a/integration-tests/junit5-tests/src/test/java/org/jboss/arquillian/integration/test/lifecycle/RepeatedTestTest.java b/integration-tests/junit5-tests/src/test/java/org/jboss/arquillian/integration/test/lifecycle/RepeatedTestTest.java index ae6b78c2b..dcc669e72 100644 --- a/integration-tests/junit5-tests/src/test/java/org/jboss/arquillian/integration/test/lifecycle/RepeatedTestTest.java +++ b/integration-tests/junit5-tests/src/test/java/org/jboss/arquillian/integration/test/lifecycle/RepeatedTestTest.java @@ -21,7 +21,6 @@ import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,7 +30,6 @@ import static org.jboss.arquillian.integration.test.lifecycle.FileWriterExtension.getTmpFilePath; import static org.jboss.arquillian.integration.test.lifecycle.FileWriterExtension.RunsWhere.SERVER; -@Disabled("https://github.com/arquillian/arquillian-core/issues/771") @ExtendWith(FileWriterExtension.class) @ArquillianTest @ExpectedTrace("repeated_test,repeated_test,repeated_test") diff --git a/junit5/container/src/test/java/org/jboss/arquillian/junit5/container/JUnitJupiterRepeatedTestCase.java b/junit5/container/src/test/java/org/jboss/arquillian/junit5/container/JUnitJupiterRepeatedTestCase.java index 7715923d8..3710d2a0f 100644 --- a/junit5/container/src/test/java/org/jboss/arquillian/junit5/container/JUnitJupiterRepeatedTestCase.java +++ b/junit5/container/src/test/java/org/jboss/arquillian/junit5/container/JUnitJupiterRepeatedTestCase.java @@ -21,10 +21,12 @@ import java.lang.reflect.Method; +import org.jboss.arquillian.junit5.extension.RunModeEvent; import org.jboss.arquillian.test.spi.LifecycleMethodExecutor; import org.jboss.arquillian.test.spi.TestMethodExecutor; import org.jboss.arquillian.test.spi.TestResult; import org.jboss.arquillian.test.spi.TestRunnerAdaptor; +import org.jboss.arquillian.test.spi.event.suite.TestLifecycleEvent; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.platform.launcher.listeners.TestExecutionSummary; @@ -44,6 +46,13 @@ protected void executeAllLifeCycles(TestRunnerAdaptor adaptor) throws Exception doAnswer(new ExecuteLifecycle()).when(adaptor).before(any(Object.class), any(Method.class), any(LifecycleMethodExecutor.class)); doAnswer(new ExecuteLifecycle()).when(adaptor).after(any(Object.class), any(Method.class), any(LifecycleMethodExecutor.class)); doAnswer(new TestExecuteLifecycle()).when(adaptor).test(any(TestMethodExecutor.class)); + doAnswer(invocation -> { + TestLifecycleEvent event = invocation.getArgument(0); + if (event instanceof RunModeEvent) { + ((RunModeEvent) event).setRunAsClient(false); + } + return null; + }).when(adaptor).fireCustomLifecycle(any(TestLifecycleEvent.class)); } @Test @@ -55,12 +64,29 @@ public void shouldExecuteRepeatedTestExactlyThreeTimes() throws Exception { // when TestExecutionSummary result = run(adaptor, ClassWithArquillianExtensionAndRepeatedTest.class); - // then — @RepeatedTest(3) must run exactly 3 times, not 9 - Assertions.assertEquals(3, result.getTestsSucceededCount()); + // then — @RepeatedTest(3) must invoke SPI lifecycle exactly 3 times, not 9 Assertions.assertEquals(0, result.getTestsFailedCount()); - Assertions.assertEquals(0, result.getTestsSkippedCount()); - assertCycle(1, Cycle.BEFORE_CLASS, Cycle.AFTER_CLASS); - assertCycle(3, Cycle.BEFORE, Cycle.TEST, Cycle.AFTER); + verify(adaptor, times(1)).beforeClass(any(Class.class), any(LifecycleMethodExecutor.class)); + verify(adaptor, times(1)).afterClass(any(Class.class), any(LifecycleMethodExecutor.class)); + verify(adaptor, times(3)).before(any(Object.class), any(Method.class), any(LifecycleMethodExecutor.class)); + verify(adaptor, times(3)).after(any(Object.class), any(Method.class), any(LifecycleMethodExecutor.class)); + verify(adaptor, times(1)).test(any(TestMethodExecutor.class)); + } + + @Test + public void shouldReportFailuresForAllRepetitions() throws Exception { + // given + TestRunnerAdaptor adaptor = mock(TestRunnerAdaptor.class); + executeAllLifeCycles(adaptor); + doAnswer(invocation -> TestResult.failed(new AssertionError("expected failure"))) + .when(adaptor).test(any(TestMethodExecutor.class)); + + // when + TestExecutionSummary result = run(adaptor, ClassWithArquillianExtensionAndRepeatedTest.class); + + // then — all 3 repetitions must report as failed + Assertions.assertEquals(3, result.getTestsFailedCount()); + verify(adaptor, times(1)).test(any(TestMethodExecutor.class)); } public static class TestExecuteLifecycle extends ExecuteLifecycle { diff --git a/junit5/core/src/main/java/org/jboss/arquillian/junit5/ArquillianExtension.java b/junit5/core/src/main/java/org/jboss/arquillian/junit5/ArquillianExtension.java index a9fd0b36e..daaf918ba 100644 --- a/junit5/core/src/main/java/org/jboss/arquillian/junit5/ArquillianExtension.java +++ b/junit5/core/src/main/java/org/jboss/arquillian/junit5/ArquillianExtension.java @@ -155,6 +155,10 @@ public void interceptTestTemplateMethod(Invocation invocation, ReflectiveI // Run as container (but only once) if (!contextStore.isRegisteredTemplate(invocationContext.getExecutable())) { result = interceptInvocation(invocation, extensionContext); + contextStore.registerTemplateResult(invocationContext.getExecutable(), result); + } else { + invocation.skip(); + result = contextStore.getRegisteredTemplateResult(invocationContext.getExecutable()); } } throwError(result); diff --git a/junit5/core/src/main/java/org/jboss/arquillian/junit5/ContextStore.java b/junit5/core/src/main/java/org/jboss/arquillian/junit5/ContextStore.java index b0c5363bd..940babab7 100644 --- a/junit5/core/src/main/java/org/jboss/arquillian/junit5/ContextStore.java +++ b/junit5/core/src/main/java/org/jboss/arquillian/junit5/ContextStore.java @@ -2,6 +2,7 @@ import java.lang.reflect.Method; +import org.jboss.arquillian.test.spi.TestResult; import org.junit.jupiter.api.extension.ExtensionContext; class ContextStore { @@ -26,17 +27,20 @@ ExtensionContext.Store getRootStore() { } private ExtensionContext.Store getTemplateStore() { - return context.getStore(ExtensionContext.Namespace.create(NAMESPACE_KEY, INTERCEPTED_TEMPLATE_NAMESPACE_KEY)); + ExtensionContext templateContext = context.getParent().orElse(context); + return templateContext.getStore(ExtensionContext.Namespace.create(NAMESPACE_KEY, INTERCEPTED_TEMPLATE_NAMESPACE_KEY)); } boolean isRegisteredTemplate(Method method) { - final ExtensionContext.Store templateStore = getTemplateStore(); + return getTemplateStore().get(method.toGenericString()) != null; + } + + void registerTemplateResult(Method method, TestResult result) { + getTemplateStore().put(method.toGenericString(), result != null ? result : TestResult.passed()); + } - final boolean isRegistered = templateStore.getOrDefault(method.toGenericString(), boolean.class, false); - if (!isRegistered) { - templateStore.put(method.toGenericString(), true); - } - return isRegistered; + TestResult getRegisteredTemplateResult(Method method) { + return getTemplateStore().get(method.toGenericString(), TestResult.class); } /**