/* * Copyright 2015-2017 the original author or authors. * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package org.junit.platform.launcher.core; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; import static org.junit.platform.launcher.EngineFilter.excludeEngines; import static org.junit.platform.launcher.EngineFilter.includeEngines; import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; import static org.junit.platform.launcher.core.LauncherFactoryForTestingPurposesOnly.createLauncher; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.platform.commons.JUnitException; import org.junit.platform.commons.util.PreconditionViolationException; import org.junit.platform.engine.ConfigurationParameters; import org.junit.platform.engine.FilterResult; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.TestEngine; import org.junit.platform.engine.UniqueId; import org.junit.platform.engine.support.hierarchical.DemoHierarchicalTestDescriptor; import org.junit.platform.engine.support.hierarchical.DemoHierarchicalTestEngine; import org.junit.platform.engine.test.TestEngineSpy; import org.junit.platform.engine.test.TestEngineStub; import org.junit.platform.launcher.PostDiscoveryFilter; import org.junit.platform.launcher.PostDiscoveryFilterStub; import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.TestPlan; import org.junit.platform.launcher.listeners.SummaryGeneratingListener; /** * @since 1.0 */ class DefaultLauncherTests { private static final String FOO = DefaultLauncherTests.class.getSimpleName() + ".foo"; private static final String BAR = DefaultLauncherTests.class.getSimpleName() + ".bar"; private static final Runnable noOp = () -> { }; @Test void constructLauncherWithoutAnyEngines() { Throwable exception = assertThrows(PreconditionViolationException.class, () -> createLauncher()); assertThat(exception).hasMessageContaining("Cannot create Launcher without at least one TestEngine"); } @Test void constructLauncherWithMultipleTestEnginesWithDuplicateIds() { JUnitException exception = assertThrows(JUnitException.class, () -> createLauncher(new DemoHierarchicalTestEngine("dummy id"), new DemoHierarchicalTestEngine("dummy id"))); assertThat(exception).hasMessageContaining("multiple engines with the same ID"); } @Test void registerTestExecutionListenersWithNullArray() { DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, () -> launcher.registerTestExecutionListeners((TestExecutionListener[]) null)); assertThat(exception).hasMessageContaining("listeners array must not be null or empty"); } @Test void registerTestExecutionListenersWithEmptyArray() { DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, () -> launcher.registerTestExecutionListeners(new TestExecutionListener[0])); assertThat(exception).hasMessageContaining("listeners array must not be null or empty"); } @Test void registerTestExecutionListenersWithArrayContainingNullElements() { DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, () -> launcher.registerTestExecutionListeners(new TestExecutionListener[] { null })); assertThat(exception).hasMessageContaining("individual listeners must not be null"); } @Test void discoverEmptyTestPlanWithEngineWithoutAnyTests() { DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine()); TestPlan testPlan = launcher.discover(request().build()); assertThat(testPlan.getRoots()).hasSize(1); } @Test void discoverTestPlanForEngineThatReturnsNullForItsRootDescriptor() { TestEngine engine = new TestEngineStub() { @Override public TestDescriptor discover(org.junit.platform.engine.EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) { return null; } }; TestPlan testPlan = createLauncher(engine).discover(request().build()); assertThat(testPlan.getRoots()).hasSize(0); } @Test void discoverTestPlanForEngineThatThrowsAnErrorInDiscoverPhase() { TestEngine engine = new TestEngineStub() { @Override public TestDescriptor discover(org.junit.platform.engine.EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) { throw new Error("ignored"); } }; TestPlan testPlan = createLauncher(engine).discover(request().build()); assertThat(testPlan.getRoots()).hasSize(0); } @Test void discoverTestPlanForEngineThatThrowsRuntimeExceptionInDiscoverPhase() { TestEngine engine = new TestEngineStub() { @Override public TestDescriptor discover(org.junit.platform.engine.EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) { throw new RuntimeException("ignored"); } }; TestPlan testPlan = createLauncher(engine).discover(request().build()); assertThat(testPlan.getRoots()).hasSize(0); } @Test void discoverTestPlanForSingleEngine() { DemoHierarchicalTestEngine engine = new DemoHierarchicalTestEngine("myEngine"); engine.addTest("test1", noOp); engine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(engine); TestPlan testPlan = launcher.discover(request().selectors(selectPackage("any")).build()); assertThat(testPlan.getRoots()).hasSize(1); TestIdentifier rootIdentifier = testPlan.getRoots().iterator().next(); assertThat(testPlan.getChildren(rootIdentifier.getUniqueId())).hasSize(2); assertThat(testPlan.getChildren("[engine:myEngine]")).hasSize(2); } @Test void discoverTestPlanForMultipleEngines() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("engine1"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("engine2"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine); TestPlan testPlan = launcher.discover( request().selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId())).build()); assertThat(testPlan.getRoots()).hasSize(2); assertThat(testPlan.getChildren(UniqueId.forEngine("engine1").toString())).hasSize(1); assertThat(testPlan.getChildren(UniqueId.forEngine("engine2").toString())).hasSize(1); } @Test void launcherWillNotExecuteEnginesIfNotIncludedByAnEngineFilter() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("first"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("second"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine); // @formatter:off TestPlan testPlan = launcher.discover( request() .selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId())) .filters(includeEngines("first")) .build()); // @formatter:on assertThat(testPlan.getRoots()).hasSize(1); TestIdentifier rootIdentifier = testPlan.getRoots().iterator().next(); assertThat(testPlan.getChildren(rootIdentifier.getUniqueId())).hasSize(1); assertThat(testPlan.getChildren(UniqueId.forEngine("first").toString())).hasSize(1); } @Test void launcherWillExecuteAllEnginesExplicitlyIncludedViaSingleEngineFilter() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("first"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("second"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine); // @formatter:off TestPlan testPlan = launcher.discover( request() .selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId())) .filters(includeEngines("first", "second")) .build()); // @formatter:on assertThat(testPlan.getRoots()).hasSize(2); } @Test void launcherWillNotExecuteEnginesExplicitlyIncludedViaMultipleCompetingEngineFilters() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("first"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("second"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine); // @formatter:off TestPlan testPlan = launcher.discover( request() .selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId())) .filters(includeEngines("first"), includeEngines("second")) .build()); // @formatter:on assertThat(testPlan.getRoots()).isEmpty(); } @Test void launcherWillNotExecuteEnginesExplicitlyExcludedByAnEngineFilter() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("first"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("second"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine); // @formatter:off TestPlan testPlan = launcher.discover( request() .selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId())) .filters(excludeEngines("second")) .build()); // @formatter:on assertThat(testPlan.getRoots()).hasSize(1); TestIdentifier rootIdentifier = testPlan.getRoots().iterator().next(); assertThat(testPlan.getChildren(rootIdentifier.getUniqueId())).hasSize(1); assertThat(testPlan.getChildren(UniqueId.forEngine("first").toString())).hasSize(1); } @Test void launcherWillExecuteEnginesHonoringBothIncludeAndExcludeEngineFilters() { DemoHierarchicalTestEngine firstEngine = new DemoHierarchicalTestEngine("first"); TestDescriptor test1 = firstEngine.addTest("test1", noOp); DemoHierarchicalTestEngine secondEngine = new DemoHierarchicalTestEngine("second"); TestDescriptor test2 = secondEngine.addTest("test2", noOp); DemoHierarchicalTestEngine thirdEngine = new DemoHierarchicalTestEngine("third"); TestDescriptor test3 = thirdEngine.addTest("test3", noOp); DefaultLauncher launcher = createLauncher(firstEngine, secondEngine, thirdEngine); // @formatter:off TestPlan testPlan = launcher.discover( request() .selectors(selectUniqueId(test1.getUniqueId()), selectUniqueId(test2.getUniqueId()), selectUniqueId(test3.getUniqueId())) .filters(includeEngines("first", "second"), excludeEngines("second")) .build()); // @formatter:on assertThat(testPlan.getRoots()).hasSize(1); TestIdentifier rootIdentifier = testPlan.getRoots().iterator().next(); assertThat(testPlan.getChildren(rootIdentifier.getUniqueId())).hasSize(1); assertThat(testPlan.getChildren(UniqueId.forEngine("first").toString())).hasSize(1); } @Test void launcherAppliesPostDiscoveryFilters() { DemoHierarchicalTestEngine engine = new DemoHierarchicalTestEngine("myEngine"); DemoHierarchicalTestDescriptor test1 = engine.addTest("test1", noOp); engine.addTest("test2", noOp); DefaultLauncher launcher = createLauncher(engine); PostDiscoveryFilter includeWithUniqueIdContainsTest = new PostDiscoveryFilterStub( descriptor -> FilterResult.includedIf(descriptor.getUniqueId().toString().contains("test")), () -> "filter1"); PostDiscoveryFilter includeWithUniqueIdContains1 = new PostDiscoveryFilterStub( descriptor -> FilterResult.includedIf(descriptor.getUniqueId().toString().contains("1")), () -> "filter2"); TestPlan testPlan = launcher.discover( // request() // .selectors(selectPackage("any")) // .filters(includeWithUniqueIdContainsTest, includeWithUniqueIdContains1) // .build()); assertThat(testPlan.getChildren(UniqueId.forEngine("myEngine").toString())).hasSize(1); assertThat(testPlan.getTestIdentifier(test1.getUniqueId().toString())).isNotNull(); } @Test void withoutConfigurationParameters_launcherPassesEmptyConfigurationParametersIntoTheExecutionRequest() { TestEngineSpy engine = new TestEngineSpy(); DefaultLauncher launcher = createLauncher(engine); launcher.execute(request().build()); ConfigurationParameters configurationParameters = engine.requestForExecution.getConfigurationParameters(); assertThat(configurationParameters.get("key").isPresent()).isFalse(); assertThat(configurationParameters.size()).isEqualTo(0); } @Test void withConfigurationParameters_launcherPassesPopulatedConfigurationParametersIntoTheExecutionRequest() { TestEngineSpy engine = new TestEngineSpy(); DefaultLauncher launcher = createLauncher(engine); launcher.execute(request().configurationParameter("key", "value").build()); ConfigurationParameters configurationParameters = engine.requestForExecution.getConfigurationParameters(); assertThat(configurationParameters.size()).isEqualTo(1); assertThat(configurationParameters.get("key").isPresent()).isTrue(); assertThat(configurationParameters.get("key").get()).isEqualTo("value"); } @Test void withoutConfigurationParameters_LookupFallsBackToSystemProperty() { System.setProperty(FOO, BAR); try { TestEngineSpy engine = new TestEngineSpy(); DefaultLauncher launcher = createLauncher(engine); launcher.execute(request().build()); ConfigurationParameters configurationParameters = engine.requestForExecution.getConfigurationParameters(); assertThat(configurationParameters.size()).isEqualTo(0); Optional<String> optionalFoo = configurationParameters.get(FOO); assertTrue(optionalFoo.isPresent(), "foo should have been picked up via system property"); assertEquals(BAR, optionalFoo.get(), "foo property"); } finally { System.clearProperty(FOO); } } @Test void withAdditionalListener() { TestEngineSpy engine = new TestEngineSpy(); SummaryGeneratingListener listener = new SummaryGeneratingListener(); DefaultLauncher launcher = createLauncher(engine); launcher.execute(request().build(), listener); assertThat(listener.getSummary()).isNotNull(); assertThat(listener.getSummary().getContainersFoundCount()).isEqualTo(1); assertThat(listener.getSummary().getTestsFoundCount()).isEqualTo(1); } }