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

eu.stamp_project.testrunner.runner.coverage.JacocoRunnerPerTestMethod Maven / Gradle / Ivy

package eu.stamp_project.testrunner.runner.coverage;

import eu.stamp_project.testrunner.EntryPoint;
import eu.stamp_project.testrunner.listener.CoveragePerTestMethod;
import eu.stamp_project.testrunner.listener.CoverageTransformer;
import eu.stamp_project.testrunner.listener.CoveredTestResult;
import eu.stamp_project.testrunner.listener.TestResult;
import eu.stamp_project.testrunner.runner.Failure;
import eu.stamp_project.testrunner.utils.ConstantsHelper;
import org.apache.commons.io.IOUtils;
import org.jacoco.core.runtime.RuntimeData;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.ResourceBundle.clearCache;

/**
 * created by Benjamin DANGLOT
 * [email protected]
 * on 27/11/18
 */
public abstract class JacocoRunnerPerTestMethod extends JacocoRunner {

    /**
     * Compute the instruction coverage of the given tests per test methods
     * Using directly this method is discouraged, since it won't avoid class loading conflict. Use {@link EntryPoint#runCoverage(String, String, String[], String[])} instead.
     *
     * @param classesDirectory             the path to the directory that contains the .class file of sources
     * @param testClassesDirectory         the path to the directory that contains the .class file of test sources
     * @param testClassNames               the fully qualified name of the test classes to execute
     * @param testMethodNames              the simple or fully qualified names of the test methods to execute
     * @return a {@link CoveragePerTestMethod} instance that contains the instruction coverage of the given tests.
     */
    public CoveragePerTestMethod runCoveragePerTestMethod(List classesDirectory,
                                                          List testClassesDirectory,
                                                          String[] testClassNames,
                                                          String[] testMethodNames) {
        final RuntimeData data = new RuntimeData();
        URLClassLoader classLoader;
        URL[] dirs = testClassesDirectory.stream()
                .map(x -> {
                    try {
                        return new File(x).toURI().toURL();
                    } catch (MalformedURLException e) {
                        throw new RuntimeException(e);
                    }
                })
                .toArray(URL[]::new);
        classLoader = new URLClassLoader(dirs, this.instrumentedClassLoader);
        try {
            for (String fullyQualifiedClassName : testClassNames) {
                String resource = ConstantsHelper.fullQualifiedNameToPath.apply(fullyQualifiedClassName) + ".class";
                this.instrumentedClassLoader.addDefinition(
                        fullyQualifiedClassName,
                        IOUtils.toByteArray(classLoader.getResourceAsStream(resource))
                );
            }
            this.runtime.startup(data);
            final CoveragePerTestMethod listener = this.executeTestPerTestMethod(data, classesDirectory, testClassNames, testMethodNames);
            if (!((TestResult) listener).getFailingTests().isEmpty()) {
                System.err.println("Some test(s) failed during computation of coverage:\n" +
                        ((TestResult) listener).getFailingTests()
                                .stream()
                                .map(Failure::toString)
                                .collect(Collectors.joining("\n"))
                );
            }
            this.runtime.shutdown();
            clearCache(this.instrumentedClassLoader);
            return listener;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected CoveredTestResult executeTest(String[] testClassNames, String[] testMethodNames, List blackList, int nbFailingLoadClass) {
        throw new UnsupportedOperationException();
    }

    protected abstract CoveragePerTestMethod executeTestPerTestMethod(RuntimeData data,
                                                                      List classesDirectory,
                                                                      String[] testClassNames,
                                                                      String[] testMethodNames);

    /**
     * @param classesDirectory     the path to the directory that contains the .class file of sources
     * @param testClassesDirectory the path to the directory that contains the .class file of test sources
     */
    public JacocoRunnerPerTestMethod(List classesDirectory, List testClassesDirectory, CoverageTransformer coverageTransformer) {
        super(classesDirectory, testClassesDirectory, coverageTransformer);
    }

    /**
     * @param classesDirectory     the path to the directory that contains the .class file of sources
     * @param testClassesDirectory the path to the directory that contains the .class file of test sources
     * @param blackList            the names of the test methods to NOT be run.
     */
    public JacocoRunnerPerTestMethod(List classesDirectory,
                                     List testClassesDirectory,
                                     List blackList,
                                     CoverageTransformer coverageTransformer) {
        this(classesDirectory, testClassesDirectory, blackList, 0, coverageTransformer);
    }

    public JacocoRunnerPerTestMethod(List classesDirectory,
                                                  List testClassesDirectory,
                                                  List blackList,
                                                  int nbFailingLoadClass,
                                                  CoverageTransformer coverageTransformer) {
        super(classesDirectory, testClassesDirectory, blackList, nbFailingLoadClass, coverageTransformer);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy