Run some JUnit tests and check coverage [message #742290] |
Thu, 20 October 2011 11:08 |
Zé arlos Messages: 15 Registered: October 2011 |
Junior Member |
|
|
Hi,
I am student of 5th year course in Master in Informatics and Computing Engineering at the Faculty of Engineering University of Porto (Portugal).
And now I am developing an Eclipse Plugin that use JUnit to run tests and JaCoCo to see the coverage of those tests.
I create a simple Plug-In Project in Eclipse with several action buttons, and for first action button I have this piece of code:
final String path = "/home/zecarlos/FEUP/runtime-EclipseApplication/Calculator/bin/";
final String targetName = "functions.test.AddTest";
final String className = "functions.Calculadora";
InputStream inputTarget = new FileInputStream(path + targetName.replace('.', '/') + ".class");
InputStream inputClass = new FileInputStream(path + className.replace('.', '/') + ".class");
// For instrumentation and runtime we need a IRuntime instance to collect execution data
final IRuntime runtime = new LoggerRuntime();
System.err.println("Instrumenting");
// The Instrumenter creates a modified version of our test target class that contains additional probes for execution data recording
final Instrumenter instr = new Instrumenter(runtime);
final byte[] instrumented = instr.instrument( inputTarget );
final Instrumenter instr2 = new Instrumenter(runtime);
final byte[] instrumented2 = instr2.instrument( inputClass );
System.err.println("Startup");
// Now we're ready to run our instrumented class and need to startup the runtime first
runtime.startup();
System.err.println("Add definition");
// In this tutorial we use a special class loader to directly load the instrumented class definition from a byte[] instances
final MemoryClassLoader memoryClassLoader = new MemoryClassLoader();
memoryClassLoader.addDefinition(targetName, instrumented);
memoryClassLoader.addDefinition(className, instrumented2);
System.err.println("Loading Class: " + targetName);
final Class<?> targetClass = memoryClassLoader.loadClass(targetName);
System.err.println("Running JUnit");
// Here we execute our test target class through its Runnable interface:
JUnitCore junit = new JUnitCore();
Result result = junit.run(targetClass);
System.out.println(result.wasSuccessful());
System.err.println("Collecting");
// At the end of test execution we collect execution data and shutdown the runtime
final ExecutionDataStore executionData = new ExecutionDataStore();
runtime.collect(executionData, null, false);
runtime.shutdown();
System.err.println("Coverage");
// Together with the original class definition we can calculate coverage information
final CoverageBuilder coverageBuilder = new CoverageBuilder();
final Analyzer analyzer = new Analyzer(executionData, coverageBuilder);
inputTarget = new FileInputStream(path + targetName.replace('.', '/') + ".class");
analyzer.analyzeClass( inputTarget );
// Let's dump some metrics and line coverage information:
for (final IClassCoverage cc : coverageBuilder.getClasses())
{
System.out.printf("Coverage of class %s%n", cc.getName());
printCounter("instructions", cc.getInstructionCounter());
printCounter("branches", cc.getBranchCounter());
printCounter("lines", cc.getLineCounter());
printCounter("methods", cc.getMethodCounter());
printCounter("complexity", cc.getComplexityCounter());
}
This code instrument the two classes (functions.test.AddTest and functions.Calculadora), save byte[] of both classes, and run only the functions.test.AddTest (class that has JUnit tests).
I have two auxiliary private methods
public static class MemoryClassLoader extends ClassLoader
{
private final Map<String, byte[]> definitions = new HashMap<String, byte[]>();
/**
* Add a in-memory representation of a class.
*/
public void addDefinition(final String name, final byte[] bytes) {
definitions.put(name, bytes);
}
@Override
protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException
{
final byte[] bytes = definitions.get(name);
if (bytes != null)
return defineClass(name, bytes, 0, bytes.length);
return super.loadClass(name, resolve);
}
}
private void printCounter(final String unit, final ICounter counter)
{
final Integer missed = Integer.valueOf(counter.getMissedCount());
final Integer total = Integer.valueOf(counter.getTotalCount());
System.out.printf("%s of %s %s missed%n", missed, total, unit);
}
If I run this example in a sample Java Project everything its ok, it do all stuffs and provide to me the coverage of JUnit test. But if I run this in a Eclipse Plug-In Project, my plugin "freeze" in line final Class<?> targetClass = memoryClassLoader.loadClass(targetName); it cannot load the Class the functions.test.AddTest...
Do you have any idea why this happen?
--
Cheers,
Zé Carlos
|
|
|
|
|
|
Re: Run some JUnit tests and check coverage [Solve] [message #783178 is a reply to message #782914] |
Wed, 25 January 2012 08:30 |
Rui Gameiro Messages: 4 Registered: September 2011 |
Junior Member |
|
|
Hi,
I understand what you're trying to do.
I read the jaCoCo API to understand the code you insert above.
I create a simple java project and run the code without problems, befroe that i try to do wahat you say and create a eclipse plug-in with one button that run the code to instrument the classes in the runtime project, but as you say it fails loading.
I try to solve the problem as you say unsuccessfully.
it is possible you put the code you use to load the classes of runtime project to the plug-in.
thanks.
Rui.
[Updated on: Wed, 25 January 2012 09:27] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.02002 seconds