下面列出了org.junit.jupiter.api.extension.ExecutionCondition#org.junit.platform.launcher.TestIdentifier 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void executionFinished(final TestIdentifier testIdentifier,
final TestExecutionResult testExecutionResult) {
// skip root
if (!testIdentifier.getParentId().isPresent()) {
return;
}
final Status status = extractStatus(testExecutionResult);
final StatusDetails statusDetails = testExecutionResult.getThrowable()
.flatMap(ResultsUtils::getStatusDetails)
.orElse(null);
if (testIdentifier.isTest()) {
stopTestCase(testIdentifier, status, statusDetails);
} else if (testExecutionResult.getStatus() != TestExecutionResult.Status.SUCCESSFUL) {
// report failed containers as fake test results
startTestCase(testIdentifier);
stopTestCase(testIdentifier, status, statusDetails);
}
stopTestContainer(testIdentifier);
}
@Override
public void executionSkipped(final TestIdentifier testIdentifier,
final String reason) {
// skip root
if (!testIdentifier.getParentId().isPresent()) {
return;
}
final TestPlan testPlan = testPlanStorage.get();
if (Objects.isNull(testPlan)) {
return;
}
reportNested(
testPlan,
testIdentifier,
SKIPPED,
new StatusDetails().setMessage(reason),
new HashSet<>()
);
}
private void stopTestContainer(final TestIdentifier testIdentifier) {
final Optional<String> maybeUuid = containers.get(testIdentifier);
if (!maybeUuid.isPresent()) {
return;
}
final String uuid = maybeUuid.get();
final TestPlan context = testPlanStorage.get();
final Set<String> children = Optional.ofNullable(context)
.map(tp -> tp.getDescendants(testIdentifier))
.orElseGet(Collections::emptySet)
.stream()
.filter(TestIdentifier::isTest)
.map(tests::get)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toCollection(HashSet::new));
if (testIdentifier.isTest()) {
tests.get(testIdentifier).ifPresent(children::add);
}
getLifecycle().updateTestContainer(uuid, container -> container.setChildren(children));
getLifecycle().stopTestContainer(uuid);
getLifecycle().writeTestContainer(uuid);
}
private void stopTestCase(final TestIdentifier testIdentifier,
final Status status,
final StatusDetails statusDetails) {
final Optional<String> maybeUuid = tests.get(testIdentifier);
if (!maybeUuid.isPresent()) {
return;
}
final String uuid = maybeUuid.get();
getLifecycle().updateTestCase(uuid, result -> {
result.setStage(Stage.FINISHED);
result.setStatus(status);
result.setStatusDetails(statusDetails);
});
getLifecycle().stopTestCase(uuid);
getLifecycle().writeTestCase(uuid);
}
public final Builder addResult(TestIdentifier identifier, TestExecutionResult result) {
DisplayName displayName = getDisplayName(identifier);
if (identifier.isTest()) {
testsBuilder().add(displayName);
}
switch (result.getStatus()) {
case SUCCESSFUL:
successfulBuilder().add(displayName);
return this;
case FAILED:
failuresBuilder().put(displayName, result.getThrowable().orElse(null));
return this;
default:
throw new AssertionError("Unhandled case in enum: " + result.getStatus());
}
}
private DisplayName getDisplayName(TestIdentifier testIdentifier) {
LinkedList<String> names = new LinkedList<>();
Optional<TestIdentifier> id = Optional.of(testIdentifier);
do {
TestIdentifier identifier = id.get();
Optional<ClassSource> classSource = identifier.getSource()
.filter(source -> source instanceof ClassSource)
.map(source -> (ClassSource) source)
.filter(source -> !source.getPosition().isPresent())
.filter(source -> classesToSkip.contains(source.getJavaClass()));
if (classSource.isPresent()) {
break;
}
names.addFirst(identifier.getDisplayName());
id = id.flatMap(testPlan::getParent);
} while (id.isPresent());
return DisplayName.create(names);
}
private String fullyQualifiedName(TestIdentifier testIdentifier) {
TestSource testSource = testIdentifier.getSource().orElse(null);
if (testSource instanceof ClassSource) {
ClassSource classSource = (ClassSource)testSource;
return classSource.getClassName();
}
if (testSource instanceof MethodSource) {
MethodSource methodSource = (MethodSource)testSource;
return methodSource.getClassName()
+ '#' + methodSource.getMethodName()
+ '(' + methodSource.getMethodParameterTypes() + ')';
}
return testIdentifier.getLegacyReportingName();
}
/**
* Extracts the class-name from the specified test identifier.
*
* @param identifier The identifier from which to extract the class-name.
* @return The class-name of the specified test identifier.
*/
public String extractClassName(TestIdentifier identifier) {
TestSource testSource = identifier.getSource().orElseThrow(() ->
new RuntimeException("Test identifier without source: " + identifier));
if (testSource instanceof ClassSource) {
return ((ClassSource)testSource).getClassName();
}
if (testSource instanceof MethodSource) {
return ((MethodSource)testSource).getClassName();
}
throw new RuntimeException("Test identifier with unknown source: " + identifier);
}
/**
* @return A formatted display name on success, {@code NULL} if the given
* identifier should be ignored.
*/
private String toName(TestIdentifier identifier) {
String name = identifier.getDisplayName();
List<Segment> segments = UniqueId.parse(identifier.getUniqueId()).getSegments();
if (!segments.isEmpty()) {
Segment lastSegment = segments.get(segments.size() - 1);
name = VINTAGE_ENGINE.equals(testEngine)
? toVintageName(identifier, lastSegment)
: toName(lastSegment);
}
return name;
}
/**
* Creates a task name for the specified {@code identifier}.
*
* @param testSuite The name of the test suite.
* @param identifier The test identifier.
* @return A task name representing the given identifier.
*/
static TaskName of(String testSuite, TestIdentifier identifier) {
TaskName result = new TaskName();
result.fullyQualifiedName = testSuite;
TestSource testSource = identifier.getSource().orElse(null);
if (testSource instanceof ClassSource) {
ClassSource classSource = (ClassSource)testSource;
result.nestedSuiteId = nestedSuiteId(testSuite, classSource.getClassName());
}
if (testSource instanceof MethodSource) {
MethodSource methodSource = (MethodSource)testSource;
result.nestedSuiteId = nestedSuiteId(testSuite, methodSource.getClassName());
result.invocation = invocation(UniqueId.parse(identifier.getUniqueId()));
result.testName = testName(methodSource.getMethodName(),
methodSource.getMethodParameterTypes());
}
return result;
}
@Override
public void executionStarted(TestIdentifier identifier) {
outputStreamMap.computeIfAbsent(identifier.getUniqueId(), key -> {
final CapturedOutputStream outputStream = new CapturedOutputStream(outputConsumer);
final CapturedOutputStream errorStream = new CapturedOutputStream(errorConsumer);
OutputCapture.register(
new PrintStream(outputStream, true),
new PrintStream(errorStream, true)
);
return outputStream;
});
}
@Override
public void executionFinished(TestIdentifier identifier, TestExecutionResult result) {
CapturedOutputStream outputStream = outputStreamMap.remove(identifier.getUniqueId());
if (null == outputStream) {
return;
}
OutputCapture.deregister();
if (isQuiet) {
if (identifier.isTest()) {
if (!SUCCESSFUL.equals(result.getStatus())) {
outputStream.output.forEach(testLogger::info);
outputStream.output.clear();
}
}
}
}
@Override
public void executionStarted(TestIdentifier testIdentifier) {
startTimes.putIfAbsent(testIdentifier.getUniqueId(), System.currentTimeMillis());
if (!testIdentifier.getParentId().isPresent()) {
if (!testPlan.getChildren(testIdentifier).isEmpty()) {
String message = "Test run started (" + testIdentifier.getDisplayName() + ")";
debugOrInfo(colorTheme.info().format(message));
}
}
if (testIdentifier.isTest()) {
String testName = configuration.formatIdentifier(testPlan, testIdentifier);
debugOrInfo("Test " + testName + " started");
}
}
public TestIdentifier findByMethodName(String testMethodName) {
final Set<TestIdentifier> descendantIdentifiers = getAllDescendants();
return descendantIdentifiers.stream()
.filter(testIdentifier -> {
TestSource testSource = testIdentifier.getSource().orElse(null);
if (testSource instanceof MethodSource) {
return ((MethodSource) testSource).getMethodName().equals(testMethodName);
}
return false;
})
.findAny()
.orElseThrow(() -> {
String message = "Could not find test method " + testMethodName + " in:\n";
String identifiers = descendantIdentifiers.stream()
.map(TestIdentifier::getUniqueId)
.collect(Collectors.joining(",\n"));
return new AssertionError(message + identifiers);
});
}
@Override
public void executionStarted(final TestIdentifier testIdentifier) {
// skip root
if (!testIdentifier.getParentId().isPresent()) {
return;
}
// create container for every TestIdentifier. We need containers for tests in order
// to support method fixtures.
startTestContainer(testIdentifier);
if (testIdentifier.isTest()) {
startTestCase(testIdentifier);
}
}
private void resetContext(final TestIdentifier testIdentifier) {
// in case of fixtures that reported within a test we need to return current
// test case uuid to allure thread local storage
Optional.of(testIdentifier)
.filter(TestIdentifier::isTest)
.flatMap(tests::get)
.ifPresent(Allure.getLifecycle()::setCurrentTestCase);
}
private void reportNested(final TestPlan testPlan,
final TestIdentifier testIdentifier,
final Status status,
final StatusDetails statusDetails,
final Set<TestIdentifier> visited) {
final Set<TestIdentifier> children = testPlan.getChildren(testIdentifier);
if (testIdentifier.isTest() || children.isEmpty()) {
startTestCase(testIdentifier);
stopTestCase(testIdentifier, status, statusDetails);
}
visited.add(testIdentifier);
children.stream()
.filter(id -> !visited.contains(id))
.forEach(child -> reportNested(testPlan, child, status, statusDetails, visited));
}
private void startTestContainer(final TestIdentifier testIdentifier) {
final String uuid = containers.getOrCreate(testIdentifier);
final TestResultContainer result = new TestResultContainer()
.setUuid(uuid)
.setName(testIdentifier.getDisplayName());
getLifecycle().startTestContainer(result);
}
public Optional<String> get(final TestIdentifier testIdentifier) {
try {
lock.readLock().lock();
return Optional.ofNullable(storage.get(testIdentifier));
} finally {
lock.readLock().unlock();
}
}
private String getOrCreate(final TestIdentifier testIdentifier) {
try {
lock.writeLock().lock();
return storage.computeIfAbsent(testIdentifier, ti -> UUID.randomUUID().toString());
} finally {
lock.writeLock().unlock();
}
}
public final Builder addSkipped(TestIdentifier identifier, @Nullable String reason) {
DisplayName displayName = getDisplayName(identifier);
if (identifier.isTest()) {
testsBuilder().add(displayName);
}
skippedBuilder().put(displayName, reason);
return this;
}
@Override
public void executionFinished(TestIdentifier identifier, TestExecutionResult result) {
try {
String name = identifier.getDisplayName();
Writer writer = new FileWriter("target/testsrun", true);
writer.write(name + "\n");
writer.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Executes a JUnit Jupiter test discovery and collects the result.
*
* @return The result of discovered tests.
*/
private Result collectTests0() {
Set<Path> classPathRoots = new HashSet<>();
classPathRoots.add(Paths.get(classDirectory.getAbsolutePath()));
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectClasspathRoots(classPathRoots))
.selectors(selectDirectory(classDirectory))
.build();
TestPlan testPlan = LauncherFactory.create().discover(request);
Result result = new Result();
for (TestIdentifier rootIdentifier : testPlan.getRoots()) {
for (TestIdentifier identifier : testPlan.getChildren(rootIdentifier)) {
String fqn = fullyQualifiedName(identifier);
Selector selector = new SuiteSelector();
Item item = new Item();
item.fullyQualifiedClassName = fqn;
item.selectors.add(selector);
item.explicit = false;
result.discoveredTests.add(item);
}
}
return result;
}
public String buildInfoName(TestIdentifier identifier) {
return buildColoredName(identifier,
colorTheme.normalName1(),
colorTheme.normalName2(),
colorTheme.normalName3()
);
}
public String buildErrorName(TestIdentifier identifier) {
return buildColoredName(identifier,
colorTheme.errorName1(),
colorTheme.errorName2(),
colorTheme.errorName3()
);
}
private String buildColoredName(TestIdentifier identifier, Color c1, Color c2, Color c3) {
String className = extractClassName(identifier);
Optional<String> methodName = extractMethodName(identifier);
StringBuilder b = new StringBuilder();
b.append(buildColoredClassName(decodeName(className), c1));
methodName.ifPresent(m -> b.append(buildColoredMethodName(m, c2, c3)));
return b.toString();
}
/**
* @return The formatted test name using the configured color theme.
*/
public String format() {
final List<TestIdentifier> path = getPath(testPlan, identifier);
testEngine = UniqueId.parse(identifier.getUniqueId())
.getEngineId()
.orElse(null);
return path.stream()
.skip(1)
.map(this::toName)
.filter(Objects::nonNull)
.collect(Collectors.joining());
}
private List<TestIdentifier> getPath(TestPlan testPlan, TestIdentifier identifier) {
List<TestIdentifier> result = new ArrayList<>();
do {
result.add(identifier);
identifier = testPlan.getParent(identifier).orElse(null);
}
while (null != identifier);
Collections.reverse(result);
return result;
}
private String toVintageName(TestIdentifier identifier, Segment lastSegment) {
final String type = lastSegment.getType();
if ("runner".equals(type)) {
String className = identifier.getDisplayName();
return colorClassName(className, colorTheme.container());
}
if ("test".equals(type)) {
final TestSource source = identifier.getSource().orElse(null);
if (null == source) {
// Caused by Parameterized test runner, display name usually is the index name in brackets.
// Ignored since the index name is repeated in the display name of the test method.
return null;
}
if (source instanceof ClassSource) {
String nestedClassName = "$" + identifier.getDisplayName().replaceFirst(".*?\\$", "");
return colorTheme.container().format(nestedClassName);
}
if (source instanceof MethodSource) {
String testName = "#" + identifier.getDisplayName();
return colorTheme.testMethod().format(testName);
}
}
return "/" + identifier.getDisplayName();
}
@Override
public void executionSkipped(TestIdentifier identifier, String reason) {
reportedIds.computeIfAbsent(identifier, key -> {
final long duration = calculateDuration(key);
final TaskName taskName = TaskName.of(testSuiteName, identifier);
eventHandler.handle(new DispatchEvent(taskName, Status.Skipped, duration));
return true;
});
}