diff --git a/.gitignore b/.gitignore index 51ee3a0a..ee81794d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Spoon files +spooned/ + # Config files .idea/ test-runner.iml diff --git a/src/main/java/eu/stamp_project/testrunner/EntryPoint.java b/src/main/java/eu/stamp_project/testrunner/EntryPoint.java index 62c397de..5b4978ec 100644 --- a/src/main/java/eu/stamp_project/testrunner/EntryPoint.java +++ b/src/main/java/eu/stamp_project/testrunner/EntryPoint.java @@ -63,6 +63,7 @@ * This class has options accessible from the outside: *

* */ public class EntryPoint { @@ -139,6 +142,12 @@ public class EntryPoint { */ public static List blackList = new ArrayList<>(); + /** + * Allows to set the level of detail at which coverage information should be reported. + * see {@link ParserOptions.CoverageTransformerDetail} + */ + public static ParserOptions.CoverageTransformerDetail coverageDetail = + ParserOptions.CoverageTransformerDetail.SUMMARIZED; // PIT OPTIONS @@ -305,6 +314,9 @@ public static Coverage runCoverage(String classpath, String targetProjectClasses EntryPoint.blackList.isEmpty() ? "" : (ParserOptions.FLAG_blackList + ConstantsHelper.WHITE_SPACE + String.join(ConstantsHelper.PATH_SEPARATOR, EntryPoint.blackList)), + EntryPoint.coverageDetail == ParserOptions.CoverageTransformerDetail.SUMMARIZED ? "" : + (ParserOptions.FLAG_coverage_detail + ConstantsHelper.WHITE_SPACE + + EntryPoint.coverageDetail.name()), }); return EntryPoint.runCoverage(javaCommand); } @@ -390,6 +402,9 @@ public static CoveragePerTestMethod runCoveragePerTestMethods(String classpath, EntryPoint.blackList.isEmpty() ? "" : (ParserOptions.FLAG_blackList + ConstantsHelper.WHITE_SPACE + String.join(ConstantsHelper.PATH_SEPARATOR, EntryPoint.blackList)), + EntryPoint.coverageDetail == ParserOptions.CoverageTransformerDetail.SUMMARIZED ? "" : + (ParserOptions.FLAG_coverage_detail + ConstantsHelper.WHITE_SPACE + + EntryPoint.coverageDetail.name()), }); try { EntryPoint.runGivenCommandLine(javaCommand); diff --git a/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorMethodDetailed.java b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorMethodDetailed.java new file mode 100644 index 00000000..e15950cb --- /dev/null +++ b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorMethodDetailed.java @@ -0,0 +1,68 @@ +package eu.stamp_project.testrunner.listener.impl; + +import eu.stamp_project.testrunner.listener.Coverage; +import eu.stamp_project.testrunner.listener.CoverageTransformer; +import org.jacoco.core.analysis.*; +import org.jacoco.core.data.ExecutionDataStore; + +import java.io.*; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class CoverageCollectorMethodDetailed implements CoverageTransformer { + @Override + public Coverage transformJacocoObject(ExecutionDataStore executionData, String classesDirectory) { + final CoverageBuilder coverageBuilder = new CoverageBuilder(); + final Analyzer analyzer = new Analyzer(executionData, coverageBuilder); + try { + analyzer.analyzeAll(new File(classesDirectory)); + } catch (IOException e) { + throw new RuntimeException(e); + } + final int[] counter = new int[2]; + final StringBuilder builderExecutionPath = new StringBuilder(); + coverageBuilder.getClasses().forEach(coverage -> { + final List listOfCountForCounterFunction = + CoverageImpl.getListOfCountForCounterFunction(coverage, ICounter::getCoveredCount); + builderExecutionPath.append(coverage.getName()) + .append(":") + .append(getCoverageInformationPerMethod(coverage, ICounter::getCoveredCount)) + .append("-"); + counter[0] += listOfCountForCounterFunction.stream() + .mapToInt(Integer::intValue) + .sum(); + counter[1] += CoverageImpl.getListOfCountForCounterFunction(coverage, ICounter::getTotalCount) + .stream() + .mapToInt(Integer::intValue) + .sum(); + }); + + Coverage coverage = new CoverageImpl( counter[0], counter[1],builderExecutionPath.toString()); + return coverage; + } + + public static String getCoverageInformationPerMethod(IClassCoverage coverage, + Function counterGetter) { + StringBuilder builder = new StringBuilder(); + coverage.getMethods() + .stream() + .filter(iMethodCoverage -> !"".equals(iMethodCoverage.getName())) + .forEach(iMethodCoverage -> { + builder.append(iMethodCoverage.getName()).append("+"); + builder.append(iMethodCoverage.getDesc()).append("+"); + builder.append(IntStream.range(iMethodCoverage.getFirstLine(), iMethodCoverage.getLastLine() + 1) + .mapToObj(iMethodCoverage::getLine) + .map(ILine::getInstructionCounter) + .map(counterGetter) + .map(Object::toString) + .collect(Collectors.joining(","))); + builder.append("|"); + }); + if (builder.length() > 0) { + builder.replace(builder.length()-1, builder.length(),""); + } + return builder.toString(); + } +} diff --git a/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorSummarization.java b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorSummarization.java index 8268e59c..0f467dc5 100644 --- a/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorSummarization.java +++ b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoverageCollectorSummarization.java @@ -77,5 +77,4 @@ public Coverage transformJacocoObject(ExecutionDataStore executionData, String c return coverage; } - } diff --git a/src/main/java/eu/stamp_project/testrunner/listener/impl/CoveragePerTestMethodImpl.java b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoveragePerTestMethodImpl.java index 1cfe500c..c06f330c 100644 --- a/src/main/java/eu/stamp_project/testrunner/listener/impl/CoveragePerTestMethodImpl.java +++ b/src/main/java/eu/stamp_project/testrunner/listener/impl/CoveragePerTestMethodImpl.java @@ -2,6 +2,7 @@ import eu.stamp_project.testrunner.listener.Coverage; import eu.stamp_project.testrunner.listener.CoveragePerTestMethod; +import eu.stamp_project.testrunner.listener.CoverageTransformer; import eu.stamp_project.testrunner.listener.TestResult; import eu.stamp_project.testrunner.runner.Loader; import eu.stamp_project.testrunner.utils.ConstantsHelper; @@ -35,15 +36,19 @@ public class CoveragePerTestMethodImpl implements CoveragePerTestMethod { protected transient SessionInfoStore sessionInfos; + protected transient CoverageTransformer coverageTransformer; + public CoveragePerTestMethodImpl() { coverageResultsMap = null; classesDirectory = null; + this.coverageTransformer = new CoverageCollectorSummarization(); } - public CoveragePerTestMethodImpl(RuntimeData data, String classesDirectory) { + public CoveragePerTestMethodImpl(RuntimeData data, String classesDirectory, CoverageTransformer coverageTransformer) { this.data = data; this.classesDirectory = classesDirectory; this.coverageResultsMap = new HashMap<>(); + this.coverageTransformer = coverageTransformer; } public String getClassesDirectory() { @@ -62,6 +67,10 @@ public SessionInfoStore getSessionInfos() { return sessionInfos; } + public CoverageTransformer getCoverageTransformer() { + return coverageTransformer; + } + public void setData(RuntimeData data) { this.data = data; } diff --git a/src/main/java/eu/stamp_project/testrunner/listener/junit4/CoveragePerJUnit4TestMethod.java b/src/main/java/eu/stamp_project/testrunner/listener/junit4/CoveragePerJUnit4TestMethod.java index e0de88af..f60450cb 100644 --- a/src/main/java/eu/stamp_project/testrunner/listener/junit4/CoveragePerJUnit4TestMethod.java +++ b/src/main/java/eu/stamp_project/testrunner/listener/junit4/CoveragePerJUnit4TestMethod.java @@ -2,6 +2,7 @@ import eu.stamp_project.testrunner.listener.Coverage; import eu.stamp_project.testrunner.listener.CoveragePerTestMethod; +import eu.stamp_project.testrunner.listener.CoverageTransformer; import eu.stamp_project.testrunner.listener.impl.CoverageCollectorSummarization; import eu.stamp_project.testrunner.listener.impl.CoverageImpl; import eu.stamp_project.testrunner.listener.impl.CoveragePerTestMethodImpl; @@ -43,8 +44,8 @@ public class CoveragePerJUnit4TestMethod extends JUnit4TestResult implements Cov */ private Map> coveragesPerMethodName; - public CoveragePerJUnit4TestMethod(RuntimeData data, String classesDirectory) { - this.internalCoverage = new CoveragePerTestMethodImpl(data, classesDirectory); + public CoveragePerJUnit4TestMethod(RuntimeData data, String classesDirectory, CoverageTransformer coverageTransformer) { + this.internalCoverage = new CoveragePerTestMethodImpl(data, classesDirectory, coverageTransformer); this.coveragesPerMethodName = new HashMap<>(); } @@ -73,8 +74,10 @@ public synchronized void testFinished(Description description) throws Exception this.internalCoverage.getSessionInfos(), false ); - CoverageCollectorSummarization coverageBilder = new CoverageCollectorSummarization(); - Coverage jUnit4Coverage = coverageBilder.transformJacocoObject(this.internalCoverage.getExecutionData(), this.internalCoverage.getClassesDirectory()); + + Coverage jUnit4Coverage = + internalCoverage.getCoverageTransformer().transformJacocoObject(this.internalCoverage.getExecutionData(), + this.internalCoverage.getClassesDirectory()); this.internalCoverage.getCoverageResultsMap().put(description.getMethodName(), jUnit4Coverage); if (isParametrized.test(description.getMethodName())) { this.collectForParametrizedTest(fromParametrizedToSimpleName.apply(description.getMethodName())); diff --git a/src/main/java/eu/stamp_project/testrunner/listener/junit5/CoveragePerJUnit5TestMethod.java b/src/main/java/eu/stamp_project/testrunner/listener/junit5/CoveragePerJUnit5TestMethod.java index 5453337c..9a080124 100644 --- a/src/main/java/eu/stamp_project/testrunner/listener/junit5/CoveragePerJUnit5TestMethod.java +++ b/src/main/java/eu/stamp_project/testrunner/listener/junit5/CoveragePerJUnit5TestMethod.java @@ -2,6 +2,7 @@ import eu.stamp_project.testrunner.listener.Coverage; import eu.stamp_project.testrunner.listener.CoveragePerTestMethod; +import eu.stamp_project.testrunner.listener.CoverageTransformer; import eu.stamp_project.testrunner.listener.impl.CoverageCollectorSummarization; import eu.stamp_project.testrunner.listener.impl.CoveragePerTestMethodImpl; import eu.stamp_project.testrunner.runner.Failure; @@ -27,8 +28,8 @@ public class CoveragePerJUnit5TestMethod extends JUnit5TestResult implements Cov private CoveragePerTestMethodImpl internalCoverage; - public CoveragePerJUnit5TestMethod(RuntimeData data, String classesDirectory) { - this.internalCoverage = new CoveragePerTestMethodImpl(data, classesDirectory); + public CoveragePerJUnit5TestMethod(RuntimeData data, String classesDirectory, CoverageTransformer coverageTransformer) { + this.internalCoverage = new CoveragePerTestMethodImpl(data, classesDirectory, coverageTransformer); } @Override @@ -54,9 +55,10 @@ public synchronized void executionFinished(TestIdentifier testIdentifier, TestEx this.internalCoverage.getSessionInfos(), false ); - - CoverageCollectorSummarization coverageBuilder = new CoverageCollectorSummarization(); - Coverage jUnit5Coverage = coverageBuilder.transformJacocoObject(this.internalCoverage.getExecutionData(), this.internalCoverage.getClassesDirectory()); + + Coverage jUnit5Coverage = + internalCoverage.getCoverageTransformer().transformJacocoObject(this.internalCoverage.getExecutionData(), + this.internalCoverage.getClassesDirectory()); this.internalCoverage.getCoverageResultsMap().put(this.toString.apply(testIdentifier), jUnit5Coverage); switch (testExecutionResult.getStatus()) { case FAILED: diff --git a/src/main/java/eu/stamp_project/testrunner/runner/ParserOptions.java b/src/main/java/eu/stamp_project/testrunner/runner/ParserOptions.java index ba265742..6db5e4b4 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/ParserOptions.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/ParserOptions.java @@ -1,5 +1,10 @@ package eu.stamp_project.testrunner.runner; +import eu.stamp_project.testrunner.listener.Coverage; +import eu.stamp_project.testrunner.listener.CoverageTransformer; +import eu.stamp_project.testrunner.listener.impl.CoverageCollectorDetailed; +import eu.stamp_project.testrunner.listener.impl.CoverageCollectorMethodDetailed; +import eu.stamp_project.testrunner.listener.impl.CoverageCollectorSummarization; import eu.stamp_project.testrunner.utils.ConstantsHelper; import java.util.ArrayList; @@ -37,6 +42,9 @@ public static ParserOptions parse(String[] args) { case FLAG_blackList: parserOptions.blackList = convertArrayToList.apply(args[++i]); break; + case FLAG_coverage_detail: + parserOptions.coverageTransformerDetail = CoverageTransformerDetail.valueOf(args[++i]); + break; case " ": case "": break; @@ -64,6 +72,9 @@ private static void usage() { usage.append(FLAG_blackList).append(ConstantsHelper.WHITE_SPACE) .append(FLAG_HELP_blackList).append(ConstantsHelper.LINE_SEPARATOR); + usage.append(FLAG_coverage_detail).append(ConstantsHelper.WHITE_SPACE) + .append(FLAG_HELP_coverage_detail).append(ConstantsHelper.LINE_SEPARATOR); + System.out.println(usage.toString()); } @@ -107,11 +118,31 @@ private static void usage() { public static final String FLAG_HELP_blackList = "This flag must be followed by the list of simple names of test methods to NOT be run. Names must be separated by the system path separator, e.g. ':' on Linux"; + + + public enum CoverageTransformerDetail { + SUMMARIZED, + DETAIL, + METHOD_DETAIL + } + /** + * This value represents at which level of detail coverage information should be provided + */ + private CoverageTransformerDetail coverageTransformerDetail; + + public static final String FLAG_coverage_detail = "--coverage-detail"; + + public static final String FLAG_HELP_coverage_detail = "The value following this flag defines the level of detail" + + " provided in the coverage information. Valid values:" + + "'SUMMARIZED' (default), 'DETAIL' or 'METHOD_DETAIL'."; + + private ParserOptions() { this.pathToCompiledClassesOfTheProject = ""; this.fullQualifiedNameOfTestClassesToRun = new String[]{}; this.testMethodNamesToRun = new String[]{}; this.blackList = new ArrayList<>(); + this.coverageTransformerDetail = CoverageTransformerDetail.SUMMARIZED; } public String getPathToCompiledClassesOfTheProject() { @@ -130,4 +161,17 @@ public List getBlackList() { return blackList; } + public CoverageTransformer getCoverageTransformer() { + switch (coverageTransformerDetail) { + case DETAIL: + return new CoverageCollectorDetailed(); + case METHOD_DETAIL: + return new CoverageCollectorMethodDetailed(); + case SUMMARIZED: + default: + return new CoverageCollectorSummarization(); + } + + } + } diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunner.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunner.java index f1f67925..1eb2f7f1 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunner.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunner.java @@ -1,6 +1,7 @@ package eu.stamp_project.testrunner.runner.coverage; import eu.stamp_project.testrunner.EntryPoint; +import eu.stamp_project.testrunner.listener.CoverageTransformer; import eu.stamp_project.testrunner.listener.CoveredTestResult; import eu.stamp_project.testrunner.listener.junit4.JUnit4Coverage; import eu.stamp_project.testrunner.listener.junit4.JUnit4TestResult; @@ -17,12 +18,12 @@ */ public class JUnit4JacocoRunner extends JacocoRunner { - public JUnit4JacocoRunner(String classesDirectory, String testClassesDirectory) { - super(classesDirectory, testClassesDirectory); + public JUnit4JacocoRunner(String classesDirectory, String testClassesDirectory, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, coverageTransformer); } - public JUnit4JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList) { - super(classesDirectory, testClassesDirectory, blackList); + public JUnit4JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, blackList, coverageTransformer); } /** @@ -38,7 +39,8 @@ public static void main(String[] args) { final JacocoRunner jacocoRunner = new JUnit4JacocoRunner(classesDirectory, testClassesDirectory, - options.getBlackList() + options.getBlackList(), + options.getCoverageTransformer() ); final String[] testClassesToRun = options.getFullQualifiedNameOfTestClassesToRun(); if (testClassesToRun.length > 1) { diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunnerPerTestMethod.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunnerPerTestMethod.java index 237c0ca3..b60af061 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunnerPerTestMethod.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit4JacocoRunnerPerTestMethod.java @@ -2,6 +2,7 @@ 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.junit4.CoveragePerJUnit4TestMethod; import eu.stamp_project.testrunner.listener.junit4.JUnit4TestResult; import eu.stamp_project.testrunner.runner.JUnit4Runner; @@ -19,8 +20,8 @@ */ public class JUnit4JacocoRunnerPerTestMethod extends JacocoRunnerPerTestMethod { - public JUnit4JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, List blackList) { - super(classesDirectory, testClassesDirectory, blackList); + public JUnit4JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, blackList, coverageTransformer); } @Override @@ -28,7 +29,7 @@ protected CoveragePerTestMethod executeTestPerTestMethod(RuntimeData data, String classesDirectory, String[] testClassNames, String[] testMethodNames) { - final CoveragePerTestMethod listener = new CoveragePerJUnit4TestMethod(data, classesDirectory); + final CoveragePerTestMethod listener = new CoveragePerJUnit4TestMethod(data, classesDirectory, coverageTransformer); JUnit4Runner.run( testClassNames, testMethodNames, @@ -52,7 +53,8 @@ public static void main(String[] args) { new JUnit4JacocoRunnerPerTestMethod( classesDirectory, testClassesDirectory, - options.getBlackList() + options.getBlackList(), + options.getCoverageTransformer() ).runCoveragePerTestMethod(classesDirectory, testClassesDirectory, options.getFullQualifiedNameOfTestClassesToRun()[0], diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunner.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunner.java index 28a6f06e..0c0e454f 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunner.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunner.java @@ -1,6 +1,7 @@ package eu.stamp_project.testrunner.runner.coverage; import eu.stamp_project.testrunner.EntryPoint; +import eu.stamp_project.testrunner.listener.CoverageTransformer; import eu.stamp_project.testrunner.listener.CoveredTestResult; import eu.stamp_project.testrunner.listener.junit5.JUnit5Coverage; import eu.stamp_project.testrunner.runner.JUnit5Runner; @@ -17,12 +18,12 @@ public class JUnit5JacocoRunner extends JacocoRunner { - public JUnit5JacocoRunner(String classesDirectory, String testClassesDirectory) { - super(classesDirectory, testClassesDirectory); + public JUnit5JacocoRunner(String classesDirectory, String testClassesDirectory, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, coverageTransformer); } - public JUnit5JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList) { - super(classesDirectory, testClassesDirectory, blackList);; + public JUnit5JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, blackList, coverageTransformer);; } @@ -40,7 +41,8 @@ public static void main(String[] args) { final JacocoRunner jacocoRunner = new JUnit5JacocoRunner(classesDirectory, testClassesDirectory, - options.getBlackList() + options.getBlackList(), + options.getCoverageTransformer() ); final String[] testClassesToRun = options.getFullQualifiedNameOfTestClassesToRun(); if (testClassesToRun.length > 1) { diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerPerTestMethod.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerPerTestMethod.java index 85fbccdb..39cbd9f8 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerPerTestMethod.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerPerTestMethod.java @@ -2,6 +2,7 @@ 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.junit5.CoveragePerJUnit5TestMethod; import eu.stamp_project.testrunner.runner.JUnit5Runner; import eu.stamp_project.testrunner.runner.ParserOptions; @@ -18,8 +19,8 @@ */ public class JUnit5JacocoRunnerPerTestMethod extends JacocoRunnerPerTestMethod { - public JUnit5JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, List blackList) { - super(classesDirectory, testClassesDirectory, blackList); + public JUnit5JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, blackList, coverageTransformer); } @Override @@ -27,7 +28,7 @@ protected CoveragePerTestMethod executeTestPerTestMethod(RuntimeData data, String classesDirectory, String[] testClassNames, String[] testMethodNames) { - final CoveragePerJUnit5TestMethod listener = new CoveragePerJUnit5TestMethod(data, classesDirectory); + final CoveragePerJUnit5TestMethod listener = new CoveragePerJUnit5TestMethod(data, classesDirectory, coverageTransformer); JUnit5Runner.run( testClassNames, testMethodNames, @@ -51,7 +52,8 @@ public static void main(String[] args) { new JUnit5JacocoRunnerPerTestMethod( classesDirectory, testClassesDirectory, - options.getBlackList() + options.getBlackList(), + options.getCoverageTransformer() ).runCoveragePerTestMethod(classesDirectory, testClassesDirectory, options.getFullQualifiedNameOfTestClassesToRun()[0], diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunner.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunner.java index 45dc93c8..585da1bc 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunner.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunner.java @@ -5,6 +5,8 @@ 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.listener.impl.CoverageCollectorDetailed; +import eu.stamp_project.testrunner.listener.impl.CoverageCollectorMethodDetailed; import eu.stamp_project.testrunner.listener.impl.CoverageCollectorSummarization; import eu.stamp_project.testrunner.runner.Failure; import eu.stamp_project.testrunner.utils.ConstantsHelper; @@ -46,12 +48,14 @@ public abstract class JacocoRunner { protected List blackList; + protected CoverageTransformer 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 */ - public JacocoRunner(String classesDirectory, String testClassesDirectory) { - this(classesDirectory, testClassesDirectory, Collections.emptyList()); + public JacocoRunner(String classesDirectory, String testClassesDirectory, CoverageTransformer coverageTransformer) { + this(classesDirectory, testClassesDirectory, Collections.emptyList(), coverageTransformer); } /** @@ -59,7 +63,7 @@ public JacocoRunner(String classesDirectory, String testClassesDirectory) { * @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 JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList) { + public JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { try { this.instrumentedClassLoader = new MemoryClassLoader( new URL[]{ @@ -73,6 +77,7 @@ public JacocoRunner(String classesDirectory, String testClassesDirectory, List blackList); - - - + + + /** @@ -216,8 +219,7 @@ public Coverage run(String classesDirectory, data.collect(executionData, sessionInfos, false); runtime.shutdown(); clearCache(this.instrumentedClassLoader); - CoverageTransformer coverageCollector = new CoverageCollectorSummarization(); - Coverage coverage = coverageCollector.transformJacocoObject(executionData, classesDirectory); + Coverage coverage = coverageTransformer.transformJacocoObject(executionData, classesDirectory); listener.setCoverageInformation(coverage); @@ -227,6 +229,7 @@ public Coverage run(String classesDirectory, throw new RuntimeException(e); } } + /** * We indicate the method to compute the coverage * @param parentClassloader @@ -354,6 +357,5 @@ public URLClassLoader getUrlClassloaderFromClassPath(String classpath) { } return classLoader; } - } diff --git a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunnerPerTestMethod.java b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunnerPerTestMethod.java index a5044fcc..61de8a0b 100644 --- a/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunnerPerTestMethod.java +++ b/src/main/java/eu/stamp_project/testrunner/runner/coverage/JacocoRunnerPerTestMethod.java @@ -2,6 +2,7 @@ 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; @@ -85,8 +86,8 @@ protected abstract CoveragePerTestMethod executeTestPerTestMethod(RuntimeData da * @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(String classesDirectory, String testClassesDirectory) { - super(classesDirectory, testClassesDirectory); + public JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, coverageTransformer); } /** @@ -94,7 +95,7 @@ public JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDire * @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(String classesDirectory, String testClassesDirectory, List blackList) { - super(classesDirectory, testClassesDirectory, blackList); + public JacocoRunnerPerTestMethod(String classesDirectory, String testClassesDirectory, List blackList, CoverageTransformer coverageTransformer) { + super(classesDirectory, testClassesDirectory, blackList, coverageTransformer); } } diff --git a/src/test/java/eu/stamp_project/testrunner/listener/CoverageTest.java b/src/test/java/eu/stamp_project/testrunner/listener/CoverageTest.java new file mode 100644 index 00000000..413f0d65 --- /dev/null +++ b/src/test/java/eu/stamp_project/testrunner/listener/CoverageTest.java @@ -0,0 +1,48 @@ +package eu.stamp_project.testrunner.listener; + +import eu.stamp_project.testrunner.AbstractTest; +import eu.stamp_project.testrunner.listener.impl.CoverageImpl; +import eu.stamp_project.testrunner.runner.ParserOptions; +import eu.stamp_project.testrunner.runner.coverage.JUnit4JacocoRunner; +import eu.stamp_project.testrunner.utils.ConstantsHelper; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class CoverageTest extends AbstractTest { + + @Test + public void compareTwoCoverages() throws Exception { + + /* + Using the api to compute the coverage on a test class + */ + + JUnit4JacocoRunner.main(new String[]{ + ParserOptions.FLAG_pathToCompiledClassesOfTheProject, TEST_PROJECT_CLASSES, + ParserOptions.FLAG_fullQualifiedNameOfTestClassToRun, "example.TestSuiteExample", + ParserOptions.FLAG_testMethodNamesToRun, "test4" + } + ); + final Coverage test4Coverage = CoverageImpl.load(); + + JUnit4JacocoRunner.main(new String[]{ + ParserOptions.FLAG_pathToCompiledClassesOfTheProject, TEST_PROJECT_CLASSES, + ParserOptions.FLAG_fullQualifiedNameOfTestClassToRun, "example.TestSuiteExample", + ParserOptions.FLAG_testMethodNamesToRun, "test8" + } + ); + final Coverage test8Coverage = CoverageImpl.load(); + + assertTrue(test4Coverage.getInstructionsCovered() > test8Coverage.getInstructionsCovered()); + assertEquals(test4Coverage.getInstructionsTotal(),test8Coverage.getInstructionsTotal()); + assertTrue(test4Coverage.isBetterThan(test8Coverage)); + + System.out.println("------- TEST 4 COVERAGE -------"); + System.out.println(String.join(ConstantsHelper.LINE_SEPARATOR, test4Coverage.getExecutionPath().split(";"))); + + System.out.println("------- TEST 8 COVERAGE -------"); + System.out.println(String.join(ConstantsHelper.LINE_SEPARATOR, test8Coverage.getExecutionPath().split(";"))); + } +} diff --git a/src/test/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerTest.java b/src/test/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerTest.java index b4aebf37..13c7c702 100644 --- a/src/test/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerTest.java +++ b/src/test/java/eu/stamp_project/testrunner/runner/coverage/JUnit5JacocoRunnerTest.java @@ -34,7 +34,7 @@ public void testWithoutNewJvmOnTestClass() throws Exception { final Coverage load = CoverageImpl.load(); assertEquals(30, load.getInstructionsCovered()); assertEquals(EntryPointTest.NUMBER_OF_INSTRUCTIONS, load.getInstructionsTotal()); - assertEquals(expectedExecutionPath , load.getExecutionPath()); + assertEquals(expectedExecutionPath, load.getExecutionPath()); } private static final String expectedExecutionPath = "tobemocked/LoginDao:0,0;tobemocked/LoginController:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;tobemocked/LoginService:0,0,0,0,0,0,0,0,0,0,0,0,0,0;example/Example:2,0,0,4,4,0,7,2,0,2,5,1,0,3;tobemocked/UserForm:0,0;"; @@ -76,4 +76,27 @@ public void testWithoutNewJvmOnTestCasesOnParametrized() throws Exception { assertEquals(EntryPointTest.NUMBER_OF_INSTRUCTIONS, load.getInstructionsTotal()); } + + private static final String expectedMethodDetailedExecutionPath = "tobemocked/LoginDao:+()V+0|login+" + + "(Ltobemocked/UserForm;)I+0-tobemocked/LoginController:+()V+0|" + + "login+(Ltobemocked/UserForm;)Ljava/lang/String;+0,0,0,0,0,0,0,0,0,0,0,0,0,0" + + "-tobemocked/LoginService:+()V+0|login+(Ltobemocked/UserForm;)Z+0,0,0,0,0,0,0|" + + "setCurrentUser+(Ljava/lang/String;)V+0,0,0,0|setLoginDao+(Ltobemocked/LoginDao;)V+0,0" + + "-example/Example:charAt+(Ljava/lang/String;I)C+2,0,0,4,4,0,7|+()V+2,0,2,5,1,0,3" + + "-tobemocked/UserForm:+()V+0|getUsername+()Ljava/lang/String;+0-"; + + + @Test + public void testMethodDetailedCoverageDetail() throws Exception { + + JUnit5JacocoRunner.main(new String[]{ + ParserOptions.FLAG_pathToCompiledClassesOfTheProject, TEST_PROJECT_CLASSES, + ParserOptions.FLAG_fullQualifiedNameOfTestClassToRun, "junit5.TestSuiteExample", + ParserOptions.FLAG_coverage_detail, ParserOptions.CoverageTransformerDetail.METHOD_DETAIL.name(), + } + ); + final Coverage load = CoverageImpl.load(); + assertEquals(expectedMethodDetailedExecutionPath, load.getExecutionPath()); + } + }