Git Product home page Git Product logo

test-runner's Introduction

Test Runner ยท Java CI Coverage Status Maven Central

This project provides a framework to run JUnit tests in a new JVM. It allows to retrieve results using serialization / deserialization.

Supported Features:

  • test: run JUnit test, the whole test class or specific test cases methods.
  • coverage: run JaCoCo to compute the instruction coverage of the given test suite or by test methods.
  • mutation score: run PIT to compute the mutation score of the test suite. Supporting descartes and gregor mutation engine.
  • JVMArgs: can specify Java Virtual Machine Arguments
  • workingDirectory: can specify where to launch the java process
  • outputStream and errStream: can customize the output stream and the error stream of the java process.
  • timeout: can specify a custom time out in milli second.
  • blacklist: can discard test methods by their name among test classes.
  • maven execution: can now executes the test using Maven. This allows users to have a complex build configured in their pom.xml.
  • the test runner supports JUnit3, JUnit4, and JUnit5. By default it runs JUnit3 or JUnit4. If you need to execute JUnit5 test methods, use the boolean in EntryPoint.
  • Parametrized JUnit 4 test methods.

/!\ WARNING the test runner is not able to run parametrized JUnit5 test methods, see #57.

API

The provided API is eu.stamp_project.testrunner.EntryPoint. This class provides several static methods to execute all the test methods of given test classes, specific test methods of a given test class, compute the code coverage with JaCoCo, etc.

Tests Execution

  1. Executing all the test methods of a test class.
// class TestResult explained below 
TestResult result = EntryPoint.runTests(String classpath, String fullQualifiedNameOfTestClass);

The classpath must contain all the dependencies required to execute the test. Elements must be separated by the system path separator. The fullQualifiedNameOfTestClass must be a correct full qualified name, e.g. my.package.TestClass. The folder that contains the compiled file of your project must be included in the classpath. The compiled (.class) of the test class to be executed must be included in the given classpath.

  1. Executing specific test methods of a given test class.
TestResult result = EntryPoint.runTests(String classpath, String fullQualifiedNameOfTestClass, String[] methodNames);

The two first parameters are the same above. The String array methodsNamescontains the name of test methods to be executed. Each of these test methods must be in the test class designated by the fullQualifiedNameOfTestClass.

Complete list:

// Execute all the test methods of a given test class
TestResult result = EntryPoint.runTests(String classpath, String fullQualifiedNameOfTestClass);

// Execute all the test methods of given test classes
TestResult result = EntryPoint.runTests(String classpath, String[] fullQualifiedNameOfTestClasses);

// Execute a specific test method of a given test class
TestResult result = EntryPoint.runTests(String classpath, String fullQualifiedNameOfTestClass, String methodName);

// Execute specific test methods of a given test class
TestResult result = EntryPoint.runTests(String classpath, String fullQualifiedNameOfTestClass, String[] methodNames);

// Execute specific test methods of given test classes
TestResult result = EntryPoint.runTests(String classpath, String[] fullQualifiedNameOfTestClasses, String[] methodNames); 
Output

The output of all runTests() API is a eu.stamp_project.testrunner.listener.TestResult.

This object provides all the information needed about the execution of test methods:

  • getRunningTests(): returns the list of test methods that have been executed.
  • getPassingTests(): returns the list of test methods that succeed.
  • getFailingTests(): returns the list of test methods that failed.
  • getAssumptionFailingTests(): returns the list of test methods that have a failing assumption. For example, in JUnit4 one can make assumptions using org.junit.Assume API, e.g. Assume.assumeTrue(myBoolean). If the assumption does not hold, it is not necessary because the program is broken but rather than the test is irrelevant in the current state, e.g. one can make dedicated test to a platform.
  • getIgnoredTests(): returns the list of test methods that are ignored.

The method TestResult#aggregate(TestResult that) allows to aggregate the results. It returns a new TestResult that contains both test results, i.e. test result of the caller and the parameter. Example:

TestResult result1 = EntryPoint.runTests(classpath, eu.stamp_project.MyFirstTest);
TestResult result2 = EntryPoint.runTests(classpath, eu.stamp_project.MySecondTest);
TestResult allResult = result1.aggregate(result2); // contains both result1 and result2

Global Coverage with JaCoCo.

API to compute the coverage:

// Compute the instruction coverage of all the test methods of a given test class
Coverage coverage = EntryPoint.runCoverage(String classpath, String targetProjectClasses, String fullQualifiedNameOfTestClass);

// Compute the instruction coverage of all the test methods of given test classes
Coverage coverage = EntryPoint.runCoverage(String classpath, String targetProjectClasses, String[] fullQualifiedNameOfTestClasses);

// Compute the instruction coverage of a specific test method of a given test class
Coverage coverage = EntryPoint.runCoverage(String classpath, String targetProjectClasses, String fullQualifiedNameOfTestClass, String methodName);

// Compute the instruction coverage of specific test methods of a given test class
Coverage coverage = EntryPoint.runCoverage(String classpath, String targetProjectClasses, String fullQualifiedNameOfTestClass, String[] methodNames);

// Compute the instruction coverage of specific test methods of given test classes
Coverage coverage = EntryPoint.runCoverage(String classpath, String targetProjectClasses, String[] fullQualifiedNameOfTestClasses, String[] methodNames); 

String targetProjectClasses must contain both the absolute paths to the binaries of the program and of the binaries of the test suite. For a typical maven project, this is would be: <path_to_project>/target/classes:<path_to_project>/target/test-classes where <path_to_project> is the path to the project under test. Note that the separator, here : is used on Linux. You must use the system separator.

Output

The output of all runCoverage() API is a eu.stamp_project.testrunner.listener.Coverage.

The object provides the two following method:

  • getInstructionsCovered(): returns the number of instruction covered by the tests.
  • getInstructionsTotal(): returns the total number of instruction.

Coverage per test methods

In the same way, you can have the coverage per test methods using runCoveragePerTestMethods() API of EntryPoint class.

Output

The output of all runCoveragePerTestMethods() API is a eu.stamp_project.testrunner.listener.CoveragePerTestMethod.

  • Map<String, Coverage> getCoverageResultsMap(): returns a map that associate the simple of a test method to its instruction coverage.
  • Coverage getCoverageOf(String testMethodName): returns the instruction coverage of a test method, specified by its simple name.

Covered results per test method

In the same way, you can have the covered results per test method using runCoveredTestResultPerTestMethods() API of EntryPoint class.

Online covered results per test method

In the same way, you can have the covered results per test method using runOnlineCoveredTestResultPerTestMethods() API of EntryPoint class.

Note that, in this case, all covered classes will be instrumented and recorded by default, or according to the jacoco parameters includes and excludes available through EntryPoint.jacocoAgentIncludes and EntryPoint.jacocoAgentExcludes respectively.

Output

The output of all runCoveredTestResultPerTestMethods() API is a eu.stamp_project.testrunner.listener.CoveredTestResultPerTestMethod.

  • Map<String, Coverage> getCoverageResultsMap(): returns a map that associates the fully qualified name of a test method (e.g. org.example#test1) to its instruction coverage.
  • Coverage getCoverageOf(String testMethodName): returns the instruction coverage of a test method, specified by its fully qualified name.
  • getRunningTests(): returns the list of test methods that have been executed.
  • getPassingTests(): returns the list of test methods that succeed.
  • getFailingTests(): returns the list of test methods that failed.
  • getAssumptionFailingTests(): returns the list of test methods that have a failing assumption. For example, in JUnit4 one can make assumptions using org.junit.Assume API, e.g. Assume.assumeTrue(myBoolean). If the assumption does not hold, it is not necessary because the program is broken but rather than the test is irrelevant in the current state, e.g. one can make dedicated test to a platform.
  • getIgnoredTests(): returns the list of test methods that are ignored.
WARNING: Detailed compressed coverage

Unlike other coverage transformers, which analyze the classes available under the source binary directories, this transformer analyzes all classes whose execution was recorded by jacoco, loading them from the system's classloader.

Using this transformer outside the online mode provided through runOnlineCoveredTestResultPerTestMethods might result in classloading issues, as the executed classes may not be available or coherent between different classloaders.

Mutation Score

The test runner can now compute the mutation using PIT.

API:

List<? extends AbstractPitResult> EntryPoint.runPit(final String classpath, final String pathToRootProject, final String filterTargetClasses, final String targetTests)

classpath is the classpath of the application. It must contains all the dependencies, the source code and the test code. pathToRootProject is the path to the root folder of the project. filterTargetClasses is a regex that matches the application source code to be mutated. targetTests is a regex that matches test classes that will be executed to compute the mutation score.

Output

The output is a list of pit result. Pit results are encapsuled in two objects, depending on the output format used.

In any case, the pit result gives the following information:

  • the full qualified name of the mutated class (application).
  • the full qualified name of the mutant operator used to mutate the class designed above.
  • the simple name of the method mutated.
  • the line number of the mutant.
  • the state of the mutant at the end of the analysis. It can be: SURVIVED, KILLED, NO_COVERAGE, TIMED_OUT, NON_VIABLE, MEMORY_ERROR.
  • the full qualified name of the test killer.

Configuration

In EntryPoint class, you have access to several fields that allow to configure the execution:

  • boolean jUnit5Mode: set JUnit5 mode. If your test are JUnit5, you must set this boolean to true.
  • boolean verbose: enable the verbose mode.
  • int timeoutInMs: the number of milliseconds to wait before considering that the execution is in timeout. In case of time out, this will end with a failure and EntryPoint will throw a java.util.concurrentTimeoutException.
  • File workingDirectory: the file descriptor to specify from where you want to execute the tests. You can use it when your test use relative path for instance. By default, it is set to null to inherit from this java process.
  • String JVMArgs: EntryPoint uses the command "java". This field allows users to specify Java Virtual Machine(JVM) arguments, e.g. -Xms4G. If this value is null, EntryPoint won't pass any JVMArgs. The value of this field should be properly formatted for command line usage, e.g. -Xms4G -Xmx8G -XX:-UseGCOverheadLimit. The args should be separated with white spaces.
  • PrintStream outPrintStream: allows to pass a customized PrintStream on which the java process called will printout. If this field is equal to null, EntryPoint with use the stdout.
  • PrintStream errPrintStream: allows to pass a customized PrintStream on which the java process called will printerr. If this field is equal to null, EntryPoint with use the stderr.
  • boolean persistence: enable this boolean in order to keep the state between runs. By default, the persistence is set to true. If you set it to false, the following values will be reset (i.e. set the default value) after each run: JVMArgs, outPrintStream, errPrintStream, workingDirectory, timeoutInMs.
  • List<String> blackList: add to this list the simple name of test methods that you want to avoid to execute.
  • MutationEngine mutationEngine: configure the mutation engine to be used. Possible values are MutationEngine.DESCARTES or MutationEngine.GREGOR. Default is MutationEngine.DESCARTES. You must use the accessor to set this value, see EntryPoint#setMutationEngine(ConstantsHelper.MutationEngine mutationEngine).
  • List<String> pitMutators: List of mutators to be used. These mutators are designed by a string. They must match with the used mutation engine. By default, it uses the default mutators for descartes and the mutator ALL for gregor. This value is modified when you change the mutation engine with EntryPoint#setMutationEngine(ConstantsHelper.MutationEngine mutationEngine).
  • AbstractParser.OutputFormat pitOutputFormat: specify the output format to be used for the mutation analyzed. Possible values are AbstractParser.OutputFormat.XML or AbstractParser.OutputFormat.CSV. Default is AbstractParser.OutputFormat.XML. The AbstractParser.OutputFormat.XML contains more information than the AbstractParser.OutputFormat.CSV.
  • String jacocoAgentIncludes: used in the online mode of coverage computation. Passed to the jacoco agent as the includes option.
  • String jacocoAgentExcludes: used in the online mode of coverage computation. Passed to the jacoco agent as the excludes option.
  • int nbFailingLoadClass: specify the number of "ClassNotFoundException" throws when running the tests.
  • boolean useOptionsFile: This options specifies to use a file to pass the options to the Runner. EntryPoint will output this file automatically. Default is false

Dependency:

You can add to your pom.xml:

<dependency>
    <groupId>eu.stamp-project</groupId>
    <artifactId>test-runner</artifactId>
    <version>2.0.8</version>
</dependency>

Development:

  1. clone:
git clone https://github.com/STAMP-project/testrunner.git
  1. build resources:
cd testrunner/src/test/resources/test-projects/
mvn install
  1. build testrunner:
cd ../../../..
mvn install

Please, open an issue if you have any question / suggestion. Pull request are welcome! ๐Ÿ˜ƒ

Licence

TestRunner is published under LGPL-3.0 (see Licence.md for further details).

Funding

TestRunner is partially funded by research project STAMP (European Commission - H2020) STAMP - European Commission - H2020

test-runner's People

Contributors

andre15silva avatar danglotb avatar dependabot[bot] avatar jesus-gorronogoitia-atos avatar lacinoire avatar martinezmatias avatar monperrus avatar spookyvale avatar surli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

test-runner's Issues

[BUG] cannot use test-runner with JUnit < 4.12

I tried with JUnit 4.5 and test-runner throws the following error:

Exception in thread "main" java.lang.NoSuchMethodError: org.junit.runner.Description.getMethodName()Ljava/lang/String;
	at eu.stamp_project.testrunner.runner.MethodFilter.shouldRun(MethodFilter.java:29)
	at org.junit.runners.ParentRunner.shouldRun(ParentRunner.java:283)
	at org.junit.runners.ParentRunner.filter(ParentRunner.java:238)
	at org.junit.runner.manipulation.Filter.apply(Filter.java:53)
	at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:35)
	at eu.stamp_project.testrunner.runner.JUnit4Runner.run(JUnit4Runner.java:62)

Refactor: something is wrong with the following condition

if (testMethodNames.length == 0) {
if (testClassNames.length > 0) {
Arrays.asList(testClassNames).forEach(testClassName -> {
try {
final Class<?> clazz = customClassLoader.loadClass(testClassName);
requestBuilder.selectors(selectClass(clazz));
} catch (ClassNotFoundException e) {
if (numberOfFailedLoadClass.incrementAndGet() > nbFailingLoadClass) {
throw new RuntimeException(e);
}
e.printStackTrace();
}
}
);
} else {
try {
requestBuilder.selectors(selectClass(customClassLoader.loadClass(testClassNames[0])));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
} else {
Arrays.asList(testMethodNames).forEach(testMethodName -> {
try {
// If there is no class name in the method name, we try the first class
if (!testMethodName.contains("#")) {
requestBuilder.selectors(selectMethod(customClassLoader.loadClass(testClassNames[0]), testMethodName));
} else {
// Else we load the fully qualified method name
String className = testMethodName.split("#")[0];
String methodName = testMethodName.split("#")[1];
requestBuilder.selectors(selectMethod(customClassLoader.loadClass(className), methodName));
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
);
}

Support multiple classes directories

Right now, test-runner assumes only two directories are passed in the targetProjectClasses, with the first one being the source classes dir, and the second the test classes dir.

final String[] splittedArgs0 = options.getPathToCompiledClassesOfTheProject().split(ConstantsHelper.PATH_SEPARATOR);
final String classesDirectory = splittedArgs0[0];
final String testClassesDirectory = splittedArgs0[1];

We should also support several classes directories, possibly through a different API which separates source and test classes in the arguments.

Optimize memory usage

Right now, the results for any API is stored as an object kept in memory for the whole execution.

When running test-runner on large projects, it is easy to reach out of memory exceptions.

Exporting the results as we compute them to a file could allow the GC to free up the space and thus use less memory.

Maven Surefire not properly loaded

Using the development instructions as per the Readme instructions, i.e

  1. clone:
git clone https://github.com/STAMP-project/testrunner.git
  1. build resources:
cd testrunner/src/test/resources/test-projects/
mvn install
  1. build testrunner:
cd ../../../..
mvn install

Causes me to get the following error:

org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.lang.NoClassDefFoundError: test-projects/target/test-classes/easymock/LoginControllerIntegrationTest (wrong name: easymock/LoginControllerIntegrationTest)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.apache.maven.surefire.util.DefaultScanResult.loadClass(DefaultScanResult.java:131)
at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:95)
at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:194)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:92)

I believe that this is due to the maven.surefire plugin not being properly loaded in the testing phase.

The path to ouput of Runners should not be hard coded

For now, the loader is looking into target/dspot/<name>.ser or appending the configuration workspace.

However, it would be great to be able to use a custom path, to use the testrunner outside of DSpot.

Thus, with #46 we could read the result from the outside.

Bump jacoco to 0.8.7

Right now test-runner version 0.8.3 of jacoco.

We should upgrade it to so we can get official support for java > 11.

Tests should also be upgraded, as a lot of them manually specify yet another version of jacoco in the classpath.

See:

final String classpath = MAVEN_HOME + "org/jacoco/org.jacoco.core/0.7.9/org.jacoco.core-0.7.9.jar" + ConstantsHelper.PATH_SEPARATOR +
MAVEN_HOME + "org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2.jar" + ConstantsHelper.PATH_SEPARATOR +
MAVEN_HOME + "commons-io/commons-io/2.5/commons-io-2.5.jar" + ConstantsHelper.PATH_SEPARATOR +
JUNIT_CP + ConstantsHelper.PATH_SEPARATOR + JUNIT5_CP;
;

FEAT: Support custom name for parametrized tests

For now, we do support JUnit4 parametrized test methods that have a default name, i.e. test[{index}], where test is the name of the test method and index is the index of the parameter used.

However, one can specify a custom name for such test using the annotation value name such as:

"{index}: array = {0}; nothingis {1}"

where variables between curly brackets {...} are replaced by values. For instance, we can have:

0: array = 1; nothingis 2`

There are two issues:

  1. the current implementation of the filter won't recognize such names and test-runner won't find any tests to be run.
  2. test-runner uses classic java command lines to run the test. Providing such names, that contain spaces and path separator ;, would be for now impossible.

Fix flaky tests

List of flaky tests:

  • eu.stamp_project.testrunner.EntryPoint#testJVMArgsAndCustomPrintStream
  • eu.stamp_project.testrunner.EntryPoint#testRunTestTestMethods

Bug when loading .ser file.

Hi @monperrus @danglotb

The last commit produces a bug when reading the serializer. 525e479

In particular, the problem is that the the bytecode located at the resources (https://github.com/STAMP-project/test-runner/tree/master/src/main/resources/runner-classes/eu/stamp_project/testrunner) where not updated. Consequently, the runner has the old version of the PATH (with the "dspot" that was removed in the previous commit).

My questions are:

  1. Why is necessary that the runner executes those classes copied from the resource folder (in the runner classpath I see the path to them test-runner/target/classes/runner-classes/) and not the compiled classes (e.g., test-runner/target/classes/runner-classes/). I understand that the idea is to pass to the runner only the classes it needs and not all.

  2. Is there an automated way to update /resources/runner-classes/?

Thanks
Regards
Matias

Error with MethodFilter?

I opened an issue on AssertFixer, because of an error when using it in Repairnator, but I think the issue is actually coming from MethodFilter in the testRunner:

16:23:44.165 [pool-3-thread-1] INFO  e.s.project.testrunner.EntryPoint - Run: java -cp /var/folders/w_/bmtv0x7d6c9871tywq4hfk0r0000gp/T/1525703016648-0/spooned-classes/:/private/var/folders/w_/bmtv0x7d6c9871tywq4hfk0r0000gp/T/test_assertfixer9133822971795612172/surli/failingProject/365127838/target/classes/:/private/var/folders/w_/bmtv0x7d6c9871tywq4hfk0r0000gp/T/test_assertfixer9133822971795612172/surli/failingProject/365127838/target/test-classes/:/var/folders/w_/bmtv0x7d6c9871tywq4hfk0r0000gp/T/test_assertfixer9133822971795612172/surli/failingProject/365127838/.m2/junit/junit/4.11/junit-4.11.jar:/var/folders/w_/bmtv0x7d6c9871tywq4hfk0r0000gp/T/test_assertfixer9133822971795612172/surli/failingProject/365127838/.m2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/urli/.m2/repository/eu/stamp-project/test-runner/1.0.1/test-runner-1.0.1.jar eu.stamp.project.testrunner.runner.test.TestRunner my.organization.ClassResourcesTest my.organization.ClassResourcesTest#testAssertSame
16:23:44.590 [pool-3-thread-1] INFO  e.s.project.testrunner.EntryPoint - Test has been run: initializationError,Failure{testCaseName='initializationError', fullQualifiedNameOfException='java.lang.Exception', messageOfFailure='No tests found matching stamp.fr.inria.filter with name of test method from org.junit.internal.requests.ClassRequest@497470ed'}
16:23:44.590 [pool-3-thread-1] INFO  eu.stamp.project.assertfixer.Main - Fixing: No tests found matching stamp.fr.inria.filter with name of test method from org.junit.internal.requests.ClassRequest@497470ed

Refactor: redirection of IO in EntryPoint

It looks like there is a clash between the management of the redirection of the IO

if (EntryPoint.verbose) {
// Redirecting to given output stream
if (EntryPoint.outPrintStream != null) {
pb.redirectOutput(Redirect.PIPE);
pb.redirectError(Redirect.PIPE);
} else {
// Redirecting to main process IO (System out/err)
pb.inheritIO();
}
} else {
// Redirecting to null file is required to avoid thread deadlocks (when verbose
// is disabled)
pb.redirectOutput(File.createTempFile("test-runner-error", ".tmp"))
.redirectErrorStream(true);
}
process = pb.start();
if (EntryPoint.verbose && EntryPoint.outPrintStream != null) {
inheritIO(process.getInputStream(), EntryPoint.outPrintStream);
inheritIO(process.getErrorStream(), EntryPoint.outPrintStream);
}

The condition EntryPoint.verbose && EntryPoint.outPrintStream != null is checked twice and has two different bodies.

pb.redirectOutput(Redirect.PIPE);
pb.redirectError(Redirect.PIPE);

vs

inheritIO(process.getInputStream(), EntryPoint.outPrintStream); 
inheritIO(process.getErrorStream(), EntryPoint.outPrintStream); 

Coverage per test method

The coverage per test method is not working.

It seems that their is some state in the coverage.

Improve isolated process error handling

The current error logging of OOM errors from the isolated test running process is not great, and can result in misleading errors such as java.lang.RuntimeException: java.nio.file.NoSuchFileException: CoveredTestResultPerTest.dat (ASSERT-KTH/flacoco#121)

For that we probably need to change the way we check if the process exited successfully here:

long startTime = System.currentTimeMillis();
boolean finished = process.waitFor(timeoutInMs, TimeUnit.MILLISECONDS);
long endTime = System.currentTimeMillis();
if (!finished) {
throw new RuntimeException("Forked process did not finish correctly. " +
"Timeout set was " + timeoutInMs + " ms, " +
"process took " + (endTime - startTime) + " ms before ending.");
}

Optimize coverage analysis

Hot spots of the test-runner process started by flacoco on math_70:

Self times
pic-selected-210729-1739-13

Expanded self times for the top result. This highlights that the most time consuming operation is analyzing the instrumented classes after execution.
pic-selected-210729-1739-56

Total times
pic-selected-210729-1740-26

Where to optimize?

  1. Coverage analysis for sure. This is the most time consuming operation with ~77% of cpu time being used there. (169s/218s)

(This is copied from ASSERT-KTH/flacoco#74)

Classloader instead of classpath

Hello,

Is it possible to provide a classloader instead of a classpath to execute the tests?
If no, do you think it is technically possible?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.