From b4cc9f034c435b63f7c955f144ffd77f9232d84f Mon Sep 17 00:00:00 2001 From: ledoyen Date: Mon, 13 Mar 2017 23:08:19 +0100 Subject: [PATCH] invoke lifecycle hooks around each dynamic tests --- .../descriptor/MethodTestDescriptor.java | 11 +++- .../descriptor/TestFactoryTestDescriptor.java | 17 +++++- .../extension/BeforeAndAfterEachTests.java | 56 +++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodTestDescriptor.java index 7a9ec4fe9ab2..887edd980c41 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodTestDescriptor.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Optional; import java.util.function.BiFunction; +import java.util.function.Consumer; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.AfterTestExecutionCallback; @@ -108,6 +109,12 @@ public SkipResult shouldBeSkipped(JupiterEngineExecutionContext context) throws @Override public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext context, DynamicTestExecutor dynamicTestExecutor) throws Exception { + executeTestBetweenBeforeAndAfterHooks(context, c -> invokeTestMethod(c, dynamicTestExecutor)); + return context; + } + + protected void executeTestBetweenBeforeAndAfterHooks(JupiterEngineExecutionContext context, + Consumer testExecutor) { ThrowableCollector throwableCollector = context.getThrowableCollector(); // @formatter:off @@ -117,7 +124,7 @@ public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext conte if (throwableCollector.isEmpty()) { invokeBeforeTestExecutionCallbacks(context); if (throwableCollector.isEmpty()) { - invokeTestMethod(context, dynamicTestExecutor); + testExecutor.accept(context); } invokeAfterTestExecutionCallbacks(context); } @@ -127,8 +134,6 @@ public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext conte // @formatter:on throwableCollector.assertEmpty(); - - return context; } private void invokeBeforeEachCallbacks(JupiterEngineExecutionContext context) { diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java index 4760febb0e64..29ab94889df2 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.extension.TestExtensionContext; import org.junit.jupiter.engine.execution.ExecutableInvoker; import org.junit.jupiter.engine.execution.JupiterEngineExecutionContext; +import org.junit.jupiter.engine.execution.ThrowableCollector; import org.junit.platform.commons.JUnitException; import org.junit.platform.commons.meta.API; import org.junit.platform.commons.util.CollectionUtils; @@ -68,6 +69,18 @@ public boolean isLeaf() { return true; } + @Override + public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext context, + DynamicTestExecutor dynamicTestExecutor) throws Exception { + ThrowableCollector throwableCollector = context.getThrowableCollector(); + + invokeTestMethod(context, dynamicTestExecutor); + + throwableCollector.assertEmpty(); + + return context; + } + @Override protected void invokeTestMethod(JupiterEngineExecutionContext context, DynamicTestExecutor dynamicTestExecutor) { TestExtensionContext testExtensionContext = (TestExtensionContext) context.getExtensionContext(); @@ -80,8 +93,8 @@ protected void invokeTestMethod(JupiterEngineExecutionContext context, DynamicTe try (Stream dynamicTestStream = toDynamicTestStream(testExtensionContext, testFactoryMethodResult)) { AtomicInteger index = new AtomicInteger(); - dynamicTestStream.forEach( - dynamicTest -> registerAndExecute(dynamicTest, index.incrementAndGet(), dynamicTestExecutor)); + dynamicTestStream.forEach(dynamicTest -> executeTestBetweenBeforeAndAfterHooks(context, + c -> registerAndExecute(dynamicTest, index.incrementAndGet(), dynamicTestExecutor))); } catch (ClassCastException ex) { throw invalidReturnTypeException(ex); diff --git a/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/BeforeAndAfterEachTests.java b/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/BeforeAndAfterEachTests.java index 0170a2a8a08d..761bbf68afc8 100644 --- a/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/BeforeAndAfterEachTests.java +++ b/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/BeforeAndAfterEachTests.java @@ -13,17 +13,21 @@ import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtendWith; @@ -151,6 +155,38 @@ public void beforeEachAndAfterEachCallbacksDeclaredOnInterfaceAndClass() { // @formatter:on } + @Test + public void beforeEachAndAfterEachCallbacksOnDynamicTests() { + LauncherDiscoveryRequest request = request().selectors(selectClass(DynamicTestTestCase.class)).build(); + + ExecutionEventRecorder eventRecorder = executeTests(request); + + assertEquals(2, eventRecorder.getTestStartedCount(), "# tests started"); + assertEquals(2, eventRecorder.getTestSuccessfulCount(), "# tests succeeded"); + assertEquals(0, eventRecorder.getTestSkippedCount(), "# tests skipped"); + assertEquals(0, eventRecorder.getTestAbortedCount(), "# tests aborted"); + assertEquals(0, eventRecorder.getTestFailedCount(), "# tests failed"); + + // @formatter:off + assertEquals(asList( + // first dynamic test + "fooBeforeEachCallback", + "beforeEachMethod", + "localTestMethod1", + "afterEachMethod", + "fooAfterEachCallback", + + // second dynamic test + "fooBeforeEachCallback", + "beforeEachMethod", + "localTestMethod2", + "afterEachMethod", + "fooAfterEachCallback" + + ), callSequence, "wrong call sequence"); + // @formatter:on + } + @Test public void beforeEachCallbackThrowsAnException() { LauncherDiscoveryRequest request = request().selectors( @@ -383,6 +419,26 @@ void afterEachInnerMethod() { } } + @ExtendWith(FooMethodLevelCallbacks.class) + private static class DynamicTestTestCase { + + @BeforeEach + void beforeEach() { + callSequence.add("beforeEachMethod"); + } + + @TestFactory + List localTest() { + return Arrays.asList(dynamicTest("dynamicTest1", () -> callSequence.add("localTestMethod1")), + dynamicTest("dynamicTest2", () -> callSequence.add("localTestMethod2"))); + } + + @AfterEach + void afterEach() { + callSequence.add("afterEachMethod"); + } + } + @ExtendWith({ FooMethodLevelCallbacks.class, ExceptionThrowingBeforeEachCallback.class, BarMethodLevelCallbacks.class }) private static class ExceptionInBeforeEachCallbackTestCase {