All Downloads are FREE. Search and download functionalities are using the official Maven repository.

app.getxray.xray.junit.customjunitxml.XmlReportData Maven / Gradle / Ivy

Go to download

Improvements for JUnit that allow you to take better advantage of JUnit 5 (jupiter engine) whenever using it together with Xray Test Management.

The newest version!
/*
 * Copyright 2015-2021 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 v2.0 which
 * accompanies this distribution and is available at
 *
 * https://www.eclipse.org/legal/epl-v20.html
 */

package app.getxray.xray.junit.customjunitxml;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static org.junit.platform.engine.TestExecutionResult.Status.ABORTED;

import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

import org.junit.platform.commons.util.ExceptionUtils;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.reporting.ReportEntry;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;


class XmlReportData {

	private final Map finishedTests = new ConcurrentHashMap<>();
	private final Map skippedTests = new ConcurrentHashMap<>();
	private final Map startInstants = new ConcurrentHashMap<>();
	private final Map endInstants = new ConcurrentHashMap<>();
	private final Map> reportEntries = new ConcurrentHashMap<>();

	private final TestPlan testPlan;
	private final Clock clock;

	XmlReportData(TestPlan testPlan, Clock clock) {
		this.testPlan = testPlan;
		this.clock = clock;
	}

	TestPlan getTestPlan() {
		return this.testPlan;
	}

	Clock getClock() {
		return this.clock;
	}

	void markSkipped(TestIdentifier testIdentifier, String reason) {
		this.skippedTests.put(testIdentifier, reason == null ? "" : reason);
	}

	void markStarted(TestIdentifier testIdentifier) {
		this.startInstants.put(testIdentifier, this.clock.instant());
	}

	void markFinished(TestIdentifier testIdentifier, TestExecutionResult result) {
		this.endInstants.put(testIdentifier, this.clock.instant());
		if (result.getStatus() == ABORTED) {
			String reason = result.getThrowable().map(ExceptionUtils::readStackTrace).orElse("");
			this.skippedTests.put(testIdentifier, reason);
		} else {
			this.finishedTests.put(testIdentifier, result);
		}
	}

	void addReportEntry(TestIdentifier testIdentifier, ReportEntry entry) {
		List entries = this.reportEntries.computeIfAbsent(testIdentifier, key -> new ArrayList<>());
		entries.add(entry);
	}

	boolean wasSkipped(TestIdentifier testIdentifier) {
		return findSkippedAncestor(testIdentifier).isPresent();
	}

	double getDurationInSeconds(TestIdentifier testIdentifier) {
		Instant startInstant = getStartInstant(testIdentifier);
		Instant endInstant = getEndInstant(testIdentifier);
		return TimeUnit.MILLISECONDS.toSeconds(Duration.between(startInstant, endInstant).toMillis());
	}

	Instant getStartInstant(TestIdentifier testIdentifier) {
		return this.startInstants.getOrDefault(testIdentifier, Instant.EPOCH);
	}

	Instant getEndInstant(TestIdentifier testIdentifier) {
		return this.endInstants.getOrDefault(testIdentifier, getStartInstant(testIdentifier));
	}

	String getSkipReason(TestIdentifier testIdentifier) {
		return findSkippedAncestor(testIdentifier)
				.map(skippedTestIdentifier -> {
					String reason = this.skippedTests.get(skippedTestIdentifier);
					if (!testIdentifier.equals(skippedTestIdentifier)) {
						reason = "parent was skipped: '" + reason + "'";
					}

					return reason;
				})
				.orElse(null);
	}

	List getResults(TestIdentifier testIdentifier) {
		return getAncestors(testIdentifier).stream()
				.map(this.finishedTests::get)
				.filter(Objects::nonNull)
				.collect(toList());
	}

	List getReportEntries(TestIdentifier testIdentifier) {
		return this.reportEntries.getOrDefault(testIdentifier, emptyList());
	}

	private Optional findSkippedAncestor(TestIdentifier testIdentifier) {
		return findAncestor(testIdentifier, this.skippedTests::containsKey);
	}

	private Optional findAncestor(TestIdentifier testIdentifier, Predicate predicate) {
		Optional current = Optional.of(testIdentifier);
		while (current.isPresent()) {
			if (predicate.test(current.get())) {
				return current;
			}
			current = this.testPlan.getParent(current.get());
		}
		return Optional.empty();
	}

	private List getAncestors(TestIdentifier testIdentifier) {
		TestIdentifier current = testIdentifier;
		List ancestors = new ArrayList<>();
		while (current != null) {
			ancestors.add(current);
			current = this.testPlan.getParent(current).orElse(null);
		}
		return ancestors;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy