/*
* 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.runner;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.platform.commons.util.CollectionUtils.getOnlyElement;
import static org.junit.platform.engine.TestExecutionResult.successful;
import static org.junit.platform.engine.discovery.ClassNameFilter.STANDARD_INCLUDE_PATTERN;
import static org.junit.platform.launcher.core.LauncherFactoryForTestingPurposesOnly.createLauncher;
import static org.junit.runner.Description.createSuiteDescription;
import static org.junit.runner.Description.createTestDescription;
import static org.junit.runner.manipulation.Filter.matchMethodDescription;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.platform.engine.EngineDiscoveryRequest;
import org.junit.platform.engine.EngineExecutionListener;
import org.junit.platform.engine.ExecutionRequest;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestEngine;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.TestTag;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.discovery.ClassNameFilter;
import org.junit.platform.engine.discovery.ClassSelector;
import org.junit.platform.engine.discovery.PackageNameFilter;
import org.junit.platform.engine.discovery.PackageSelector;
import org.junit.platform.engine.discovery.UniqueIdSelector;
import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.platform.engine.support.descriptor.EngineDescriptor;
import org.junit.platform.engine.support.descriptor.MethodSource;
import org.junit.platform.engine.support.hierarchical.DemoHierarchicalContainerDescriptor;
import org.junit.platform.engine.support.hierarchical.DemoHierarchicalTestDescriptor;
import org.junit.platform.engine.support.hierarchical.DemoHierarchicalTestEngine;
import org.junit.platform.engine.test.TestDescriptorStub;
import org.junit.platform.engine.test.TestEngineStub;
import org.junit.platform.launcher.EngineFilter;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.suite.api.ExcludeClassNamePatterns;
import org.junit.platform.suite.api.ExcludeEngines;
import org.junit.platform.suite.api.ExcludePackages;
import org.junit.platform.suite.api.ExcludeTags;
import org.junit.platform.suite.api.IncludeClassNamePatterns;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.IncludePackages;
import org.junit.platform.suite.api.IncludeTags;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.UseTechnicalNames;
import org.junit.runner.Description;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
/**
* Tests for the {@link JUnitPlatform} runner.
*
* @since 1.0
*/
class JUnitPlatformRunnerTests {
@Nested
class Discovery {
@Test
void requestsClassSelectorForAnnotatedClassWhenNoAdditionalAnnotationsArePresent() throws Exception {
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassSelector> selectors = request.getSelectorsByType(ClassSelector.class);
assertThat(selectors).hasSize(1);
ClassSelector classSelector = getOnlyElement(selectors);
assertEquals(TestCase.class, classSelector.getJavaClass());
}
@Test
void requestsClassSelectorsWhenSelectClassesAnnotationIsPresent() throws Exception {
@SelectClasses({ Short.class, Byte.class })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassSelector> selectors = request.getSelectorsByType(ClassSelector.class);
assertThat(selectors).hasSize(2);
assertEquals(Short.class, selectors.get(0).getJavaClass());
assertEquals(Byte.class, selectors.get(1).getJavaClass());
}
@Test
void requestsPackageSelectorsWhenPackagesAnnotationIsPresent() throws Exception {
@SelectPackages({ "foo", "bar" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<PackageSelector> selectors = request.getSelectorsByType(PackageSelector.class);
assertThat(selectors).hasSize(2);
assertEquals("foo", selectors.get(0).getPackageName());
assertEquals("bar", selectors.get(1).getPackageName());
}
@Test
void addsPackageFiltersToRequestWhenIncludePackageAnnotationIsPresent() throws Exception {
@IncludePackages({ "includedpackage1", "includedpackage2" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<PackageNameFilter> filters = request.getDiscoveryFiltersByType(PackageNameFilter.class);
assertThat(filters).hasSize(1);
PackageNameFilter filter = filters.get(0);
assertTrue(filter.apply("includedpackage1.TestClass").included());
assertTrue(filter.apply("includedpackage2.TestClass").included());
assertTrue(filter.apply("excludedpackage1.TestClass").excluded());
}
@Test
void addsPackageFiltersToRequestWhenExcludePackageAnnotationIsPresent() throws Exception {
@ExcludePackages({ "excludedpackage1", "excludedpackage2" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<PackageNameFilter> filters = request.getDiscoveryFiltersByType(PackageNameFilter.class);
assertThat(filters).hasSize(1);
PackageNameFilter filter = filters.get(0);
assertTrue(filter.apply("includedpackage1.TestClass").included());
assertTrue(filter.apply("excludedpackage1.TestClass").excluded());
assertTrue(filter.apply("excludedpackage2.TestClass").excluded());
}
@Test
void addsTagFilterToRequestWhenIncludeTagsAnnotationIsPresent() throws Exception {
@IncludeTags({ "foo", "bar" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<PostDiscoveryFilter> filters = request.getPostDiscoveryFilters();
assertThat(filters).hasSize(1);
PostDiscoveryFilter filter = filters.get(0);
assertTrue(filter.apply(testDescriptorWithTag("foo")).included());
assertTrue(filter.apply(testDescriptorWithTag("bar")).included());
assertTrue(filter.apply(testDescriptorWithTag("baz")).excluded());
}
@Test
void addsTagFilterToRequestWhenExcludeTagsAnnotationIsPresent() throws Exception {
@ExcludeTags({ "foo", "bar" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<PostDiscoveryFilter> filters = request.getPostDiscoveryFilters();
assertThat(filters).hasSize(1);
PostDiscoveryFilter filter = filters.get(0);
assertTrue(filter.apply(testDescriptorWithTag("foo")).excluded());
assertTrue(filter.apply(testDescriptorWithTag("bar")).excluded());
assertTrue(filter.apply(testDescriptorWithTag("baz")).included());
}
@Test
void addsEngineFiltersToRequestWhenIncludeEnginesOrExcludeEnginesAnnotationsArePresent() throws Exception {
@IncludeEngines({ "foo", "bar", "baz" })
@ExcludeEngines({ "bar", "quux" })
class TestCase {
}
TestEngine fooEngine = new TestEngineStub("foo");
TestEngine barEngine = new TestEngineStub("bar");
TestEngine bazEngine = new TestEngineStub("baz");
TestEngine quuxEngine = new TestEngineStub("quux");
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<EngineFilter> filters = request.getEngineFilters();
assertThat(filters).hasSize(2);
EngineFilter includeFilter = filters.get(0);
assertTrue(includeFilter.apply(fooEngine).included());
assertTrue(includeFilter.apply(barEngine).included());
assertTrue(includeFilter.apply(bazEngine).included());
assertTrue(includeFilter.apply(quuxEngine).excluded());
EngineFilter excludeFilter = filters.get(1);
assertTrue(excludeFilter.apply(fooEngine).included());
assertTrue(excludeFilter.apply(barEngine).excluded());
assertTrue(excludeFilter.apply(bazEngine).included());
assertTrue(excludeFilter.apply(quuxEngine).excluded());
}
@Test
void addsDefaultClassNameFilterToRequestWhenFilterClassNameAnnotationIsNotPresentOnTestSuite()
throws Exception {
@SelectPackages("foo")
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(STANDARD_INCLUDE_PATTERN);
}
@Test
void addsDefaultClassNameFilterToRequestWhenFilterClassNameAnnotationIsNotPresentOnTestClass()
throws Exception {
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(filters).isEmpty();
}
@Test
void addsSingleExplicitClassNameFilterToRequestWhenIncludeClassNamePatternsAnnotationIsPresent()
throws Exception {
@IncludeClassNamePatterns(".*Foo")
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(".*Foo");
}
@Test
void addsSingleClassNameFilterToRequestWhenExcludeClassNamePatternsAnnotationIsPresent() throws Exception {
@ExcludeClassNamePatterns(".*Foo")
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(".*Foo");
}
@Test
void addsMultipleExplicitClassNameFilterToRequestWhenIncludeClassNamePatternsAnnotationIsPresent()
throws Exception {
@IncludeClassNamePatterns({ ".*Foo", "Bar.*" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(".*Foo", "Bar.*");
}
@Test
void addsMultipleClassNameFilterToRequestWhenExcludeClassNamePatternsAnnotationIsPresent() throws Exception {
@ExcludeClassNamePatterns({ ".*Foo", "Bar.*" })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(".*Foo", "Bar.*");
}
@Test
void usesStandardIncludePatternWhenIncludeClassNamePatternsAnnotationIsPresentWithoutArguments()
throws Exception {
@IncludeClassNamePatterns
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains(STANDARD_INCLUDE_PATTERN);
}
@Test
void doesNotAddClassNameFilterWhenIncludeClassNamePatternsAnnotationIsPresentWithEmptyArguments()
throws Exception {
@IncludeClassNamePatterns({})
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(filters).isEmpty();
}
@Test
void doesNotAddClassNameFilterWhenExcludeClassNamePatternsAnnotationIsPresentWithEmptyArguments()
throws Exception {
@ExcludeClassNamePatterns({})
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(filters).isEmpty();
}
@Test
void trimsArgumentsOfIncludeClassNamePatternsAnnotation() throws Exception {
@IncludeClassNamePatterns({ " foo", "bar " })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains("'foo'", "'bar'");
}
@Test
void trimsArgumentsOfExcludeClassNamePatternsAnnotation() throws Exception {
@ExcludeClassNamePatterns({ " foo", "bar " })
class TestCase {
}
LauncherDiscoveryRequest request = instantiateRunnerAndCaptureGeneratedRequest(TestCase.class);
List<ClassNameFilter> filters = request.getDiscoveryFiltersByType(ClassNameFilter.class);
assertThat(getOnlyElement(filters).toString()).contains("'foo'", "'bar'");
}
@Test
void convertsTestIdentifiersIntoDescriptions() throws Exception {
TestDescriptor container1 = new TestDescriptorStub(UniqueId.root("root", "container1"), "container1");
container1.addChild(new TestDescriptorStub(UniqueId.root("root", "test1"), "test1"));
TestDescriptor container2 = new TestDescriptorStub(UniqueId.root("root", "container2"), "container2");
container2.addChild(new TestDescriptorStub(UniqueId.root("root", "test2a"), "test2a"));
container2.addChild(new TestDescriptorStub(UniqueId.root("root", "test2b"), "test2b"));
TestPlan testPlan = TestPlan.from(asList(container1, container2));
Launcher launcher = mock(Launcher.class);
when(launcher.discover(any())).thenReturn(testPlan);
JUnitPlatform runner = new JUnitPlatform(TestClass.class, launcher);
Description runnerDescription = runner.getDescription();
assertEquals(createSuiteDescription(TestClass.class), runnerDescription);
List<Description> containerDescriptions = runnerDescription.getChildren();
assertThat(containerDescriptions).hasSize(2);
assertEquals(suiteDescription("[root:container1]"), containerDescriptions.get(0));
assertEquals(suiteDescription("[root:container2]"), containerDescriptions.get(1));
List<Description> testDescriptions = containerDescriptions.get(0).getChildren();
assertEquals(testDescription("[root:test1]"), getOnlyElement(testDescriptions));
testDescriptions = containerDescriptions.get(1).getChildren();
assertThat(testDescriptions).hasSize(2);
assertEquals(testDescription("[root:test2a]"), testDescriptions.get(0));
assertEquals(testDescription("[root:test2b]"), testDescriptions.get(1));
}
}
@Nested
class Filtering {
@Test
void appliesFilter() throws Exception {
TestDescriptor originalParent1 = new TestDescriptorStub(UniqueId.root("root", "parent1"), "parent1");
originalParent1.addChild(new TestDescriptorStub(UniqueId.root("root", "leaf1"), "leaf1"));
TestDescriptor originalParent2 = new TestDescriptorStub(UniqueId.root("root", "parent2"), "parent2");
originalParent2.addChild(new TestDescriptorStub(UniqueId.root("root", "leaf2a"), "leaf2a"));
originalParent2.addChild(new TestDescriptorStub(UniqueId.root("root", "leaf2b"), "leaf2b"));
TestPlan fullTestPlan = TestPlan.from(asList(originalParent1, originalParent2));
TestDescriptor filteredParent = new TestDescriptorStub(UniqueId.root("root", "parent2"), "parent2");
filteredParent.addChild(new TestDescriptorStub(UniqueId.root("root", "leaf2b"), "leaf2b"));
TestPlan filteredTestPlan = TestPlan.from(singleton(filteredParent));
Launcher launcher = mock(Launcher.class);
ArgumentCaptor<LauncherDiscoveryRequest> captor = ArgumentCaptor.forClass(LauncherDiscoveryRequest.class);
when(launcher.discover(captor.capture())).thenReturn(fullTestPlan).thenReturn(filteredTestPlan);
JUnitPlatform runner = new JUnitPlatform(TestClass.class, launcher);
runner.filter(matchMethodDescription(testDescription("[root:leaf2b]")));
LauncherDiscoveryRequest lastDiscoveryRequest = captor.getValue();
List<UniqueIdSelector> uniqueIdSelectors = lastDiscoveryRequest.getSelectorsByType(UniqueIdSelector.class);
assertEquals("[root:leaf2b]", getOnlyElement(uniqueIdSelectors).getUniqueId().toString());
Description parentDescription = getOnlyElement(runner.getDescription().getChildren());
assertEquals(suiteDescription("[root:parent2]"), parentDescription);
Description testDescription = getOnlyElement(parentDescription.getChildren());
assertEquals(testDescription("[root:leaf2b]"), testDescription);
}
@Test
void throwsNoTestsRemainExceptionWhenNoTestIdentifierMatchesFilter() throws Exception {
TestPlan testPlan = TestPlan.from(singleton(new TestDescriptorStub(UniqueId.root("root", "test"), "test")));
Launcher launcher = mock(Launcher.class);
when(launcher.discover(any())).thenReturn(testPlan);
JUnitPlatform runner = new JUnitPlatform(TestClass.class, launcher);
assertThrows(NoTestsRemainException.class,
() -> runner.filter(matchMethodDescription(suiteDescription("[root:doesNotExist]"))));
}
}
@Nested
class Execution {
@Test
void notifiesRunListenerOfTestExecution() throws Exception {
DemoHierarchicalTestEngine engine = new DemoHierarchicalTestEngine("dummy");
engine.addTest("failingTest", () -> fail("expected to fail"));
engine.addTest("succeedingTest", () -> {
});
engine.addTest("abortedTest", () -> assumeFalse(true));
engine.addTest("skippedTest", () -> fail("never called")).markSkipped("should be skipped");
RunListener runListener = mock(RunListener.class);
RunNotifier notifier = new RunNotifier();
notifier.addListener(runListener);
new JUnitPlatform(TestClass.class, createLauncher(engine)).run(notifier);
InOrder inOrder = inOrder(runListener);
inOrder.verify(runListener).testStarted(testDescription("[engine:dummy]/[test:failingTest]"));
inOrder.verify(runListener).testFailure(any());
inOrder.verify(runListener).testFinished(testDescription("[engine:dummy]/[test:failingTest]"));
inOrder.verify(runListener).testStarted(testDescription("[engine:dummy]/[test:succeedingTest]"));
inOrder.verify(runListener).testFinished(testDescription("[engine:dummy]/[test:succeedingTest]"));
inOrder.verify(runListener).testStarted(testDescription("[engine:dummy]/[test:abortedTest]"));
inOrder.verify(runListener).testAssumptionFailure(any());
inOrder.verify(runListener).testFinished(testDescription("[engine:dummy]/[test:abortedTest]"));
inOrder.verify(runListener).testIgnored(testDescription("[engine:dummy]/[test:skippedTest]"));
inOrder.verifyNoMoreInteractions();
}
@Test
void supportsDynamicTestRegistration() throws Exception {
RunListener runListener = mock(RunListener.class);
RunNotifier notifier = new RunNotifier();
// notifier.addListener(new LoggingRunListener());
notifier.addListener(runListener);
new JUnitPlatform(TestClass.class, createLauncher(new DynamicTestEngine())).run(notifier);
InOrder inOrder = inOrder(runListener);
inOrder.verify(runListener).testStarted(testDescription("[engine:dynamic]/[container:1]/[test:1]"));
inOrder.verify(runListener).testFinished(testDescription("[engine:dynamic]/[container:1]/[test:1]"));
inOrder.verify(runListener).testStarted(testDescription("[engine:dynamic]/[container:1]/[test:2]"));
inOrder.verify(runListener).testFinished(testDescription("[engine:dynamic]/[container:1]/[test:2]"));
inOrder.verifyNoMoreInteractions();
}
@Test
void reportsIgnoredEventsForLeavesWhenContainerIsSkipped() throws Exception {
UniqueId uniqueEngineId = UniqueId.forEngine("engine");
TestDescriptor engineDescriptor = new EngineDescriptor(uniqueEngineId, "engine");
TestDescriptor container = new TestDescriptorStub(UniqueId.root("root", "container"), "container");
container.addChild(new TestDescriptorStub(UniqueId.root("root", "leaf"), "leaf"));
engineDescriptor.addChild(container);
TestEngine engine = mock(TestEngine.class);
when(engine.getId()).thenReturn("engine");
when(engine.discover(any(), eq(uniqueEngineId))).thenReturn(engineDescriptor);
doAnswer(invocation -> {
ExecutionRequest request = invocation.getArgument(0);
EngineExecutionListener listener = request.getEngineExecutionListener();
listener.executionStarted(engineDescriptor);
listener.executionSkipped(container, "deliberately skipped container");
listener.executionFinished(engineDescriptor, successful());
return null;
}).when(engine).execute(any());
RunListener runListener = mock(RunListener.class);
RunNotifier notifier = new RunNotifier();
notifier.addListener(runListener);
new JUnitPlatform(TestClass.class, createLauncher(engine)).run(notifier);
verify(runListener).testIgnored(testDescription("[root:leaf]"));
verifyNoMoreInteractions(runListener);
}
}
@Nested
class Descriptions {
@Test
void descriptionForJavaMethodAndClassSources() throws Exception {
DemoHierarchicalTestEngine engine = new DemoHierarchicalTestEngine("dummy");
Method failingTest = getClass().getDeclaredMethod("failingTest");
DemoHierarchicalContainerDescriptor containerDescriptor = engine.addContainer("uniqueContainerName",
"containerDisplayName", new ClassSource(getClass()));
containerDescriptor.addChild(
new DemoHierarchicalTestDescriptor(containerDescriptor.getUniqueId().append("test", "failingTest"),
"testDisplayName", new MethodSource(failingTest), () -> {
}));
JUnitPlatform platformRunner = new JUnitPlatform(TestClass.class, createLauncher(engine));
List<Description> children = platformRunner.getDescription().getChildren();
assertEquals(1, children.size());
Description engineDescription = children.get(0);
assertEquals("dummy", engineDescription.getDisplayName());
Description containerDescription = getOnlyElement(engineDescription.getChildren());
Description testDescription = getOnlyElement(containerDescription.getChildren());
// @formatter:off
assertAll(
() -> assertEquals("dummy", engineDescription.getDisplayName(), "engine display name"),
() -> assertEquals("dummy", engineDescription.getClassName(), "engine class name"),
() -> assertNull(engineDescription.getMethodName(), "engine method name"),
() -> assertEquals("containerDisplayName", containerDescription.getDisplayName(), "container display name"),
() -> assertEquals("containerDisplayName", containerDescription.getClassName(), "container class name"),
() -> assertNull(containerDescription.getMethodName(), "container method name"),
() -> assertEquals("testDisplayName(containerDisplayName)", testDescription.getDisplayName(), "test display name"),
() -> assertEquals("containerDisplayName", testDescription.getClassName(), "test class name"),
() -> assertEquals("testDisplayName", testDescription.getMethodName(), "test method name")
);
// @formatter:on
}
@Test
void descriptionForJavaMethodAndClassSourcesUsingTechnicalNames() throws Exception {
DemoHierarchicalTestEngine engine = new DemoHierarchicalTestEngine("dummy");
Method failingTest = getClass().getDeclaredMethod("failingTest");
DemoHierarchicalContainerDescriptor containerDescriptor = engine.addContainer("uniqueContainerName",
"containerDisplayName", new ClassSource(getClass()));
containerDescriptor.addChild(
new DemoHierarchicalTestDescriptor(containerDescriptor.getUniqueId().append("test", "failingTest"),
"testDisplayName", new MethodSource(failingTest), () -> {
}));
JUnitPlatform platformRunner = new JUnitPlatform(TestClassWithTechnicalNames.class, createLauncher(engine));
List<Description> children = platformRunner.getDescription().getChildren();
assertEquals(1, children.size());
Description engineDescription = children.get(0);
assertEquals("dummy", engineDescription.getDisplayName());
Description containerDescription = getOnlyElement(engineDescription.getChildren());
Description testDescription = getOnlyElement(containerDescription.getChildren());
// @formatter:off
assertAll(
() -> assertEquals("dummy", engineDescription.getDisplayName(), "engine display name"),
() -> assertEquals("dummy", engineDescription.getClassName(), "engine class name"),
() -> assertNull(engineDescription.getMethodName(), "engine method name"),
() -> assertEquals(getClass().getName(), containerDescription.getDisplayName(), "container display name"),
() -> assertEquals(getClass().getName(), containerDescription.getClassName(), "container class name"),
() -> assertNull(containerDescription.getMethodName(), "container method name"),
() -> assertEquals("failingTest(" + getClass().getName() + ")", testDescription.getDisplayName(), "test display name"),
() -> assertEquals(getClass().getName(), testDescription.getClassName(), "test class name"),
() -> assertEquals("failingTest", testDescription.getMethodName(), "test method name")
);
// @formatter:on
}
void failingTest() {
// not actually invoked
}
}
// -------------------------------------------------------------------------
private static Description suiteDescription(String uniqueId) {
return createSuiteDescription(uniqueId, uniqueId);
}
private static Description testDescription(String uniqueId) {
return createTestDescription(uniqueId, uniqueId, uniqueId);
}
private TestDescriptor testDescriptorWithTag(String tag) {
TestDescriptor testDescriptor = mock(TestDescriptor.class);
when(testDescriptor.getTags()).thenReturn(singleton(TestTag.create(tag)));
return testDescriptor;
}
private LauncherDiscoveryRequest instantiateRunnerAndCaptureGeneratedRequest(Class<?> testClass)
throws InitializationError {
Launcher launcher = mock(Launcher.class);
ArgumentCaptor<LauncherDiscoveryRequest> captor = ArgumentCaptor.forClass(LauncherDiscoveryRequest.class);
when(launcher.discover(captor.capture())).thenReturn(TestPlan.from(emptySet()));
new JUnitPlatform(testClass, launcher);
return captor.getValue();
}
private static class TestClass {
}
@UseTechnicalNames
private static class TestClassWithTechnicalNames {
}
private static class DynamicTestEngine implements TestEngine {
@Override
public String getId() {
return "dynamic";
}
@Override
public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
return new EngineDescriptor(uniqueId, "Dynamic Engine");
}
@Override
public void execute(ExecutionRequest request) {
EngineExecutionListener engineExecutionListener = request.getEngineExecutionListener();
TestDescriptor root = request.getRootTestDescriptor();
TestDescriptor container = new DemoContainerTestDescriptor(root.getUniqueId().append("container", "1"),
"container #1");
root.addChild(container);
engineExecutionListener.dynamicTestRegistered(container);
engineExecutionListener.executionStarted(container);
UniqueId containerUid = container.getUniqueId();
TestDescriptor dynamicTest1 = new DemoTestTestDescriptor(containerUid.append("test", "1"),
"dynamic test #1");
container.addChild(dynamicTest1);
engineExecutionListener.dynamicTestRegistered(dynamicTest1);
engineExecutionListener.executionStarted(dynamicTest1);
engineExecutionListener.executionFinished(dynamicTest1, TestExecutionResult.successful());
TestDescriptor dynamicTest2 = new DemoTestTestDescriptor(containerUid.append("test", "2"),
"dynamic test #2");
container.addChild(dynamicTest2);
engineExecutionListener.dynamicTestRegistered(dynamicTest2);
engineExecutionListener.executionStarted(dynamicTest2);
engineExecutionListener.executionFinished(dynamicTest2, TestExecutionResult.successful());
engineExecutionListener.executionFinished(container, TestExecutionResult.successful());
}
}
private static class DemoContainerTestDescriptor extends AbstractTestDescriptor {
DemoContainerTestDescriptor(UniqueId uniqueId, String displayName) {
super(uniqueId, displayName);
}
@Override
public Type getType() {
return Type.CONTAINER;
}
}
private static class DemoTestTestDescriptor extends AbstractTestDescriptor {
DemoTestTestDescriptor(UniqueId uniqueId, String displayName) {
super(uniqueId, displayName);
}
@Override
public Type getType() {
return Type.TEST;
}
}
}