So I recently installed OpenClover and want to parse the outputted XML file. My goal is to obtain coverage information and place that information in a Java class.
The imagine above shows exactly what I want to do. That is In my class Calculator I have a method "sum" I want to know that the Test testSum that exist in the class Test covered the method "sum".
The problem is that looking at the XML output from OpenClover I'm not sure how to make this connection.
Here is the XML output:
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1586952302126" clover="4.4.1">
<project name="OpenCloverTest 1.0-SNAPSHOT" timestamp="1586952298327">
<metrics coveredelements="8" complexity="5" loc="24" methods="4" classes="2" statements="11" packages="1" coveredconditionals="2" coveredmethods="2" elements="17" ncloc="24" files="2" conditionals="2" coveredstatements="4"/>
<package name="default-pkg">
<metrics coveredelements="8" complexity="5" loc="24" methods="4" classes="2" statements="11" coveredconditionals="2" coveredmethods="2" elements="17" ncloc="24" files="2" conditionals="2" coveredstatements="4"/>
<file path="F:\MyProj\Projects\OpenCloverTest\src\main\java\Calculator.java" name="Calculator.java">
<metrics coveredelements="8" coveredconditionals="2" complexity="4" loc="17" coveredmethods="2" methods="3" elements="13" classes="1" ncloc="17" statements="8" conditionals="2" coveredstatements="4"/>
<class name="Calculator">
<metrics coveredelements="8" coveredconditionals="2" complexity="4" coveredmethods="2" methods="3" elements="13" statements="8" conditionals="2" coveredstatements="4"/>
</class>
<line complexity="2" visibility="public" signature="sum(int,int) : int" num="2" count="2" type="method"/>
<line num="3" count="2" type="stmt"/>
<line falsecount="1" truecount="1" num="3" type="cond"/>
<line num="4" count="1" type="stmt"/>
<line num="6" count="1" type="stmt"/>
<line complexity="1" visibility="public" signature="mulitpliy(int,int) : int" num="8" count="1" type="method"/>
<line num="9" count="1" type="stmt"/>
<line complexity="1" visibility="public" signature="division(int,int) : int" num="11" count="0" type="method"/>
<line num="12" count="0" type="stmt"/>
<line num="13" count="0" type="stmt"/>
<line num="14" count="0" type="stmt"/>
<line num="15" count="0" type="stmt"/>
</file>
<file path="F:\MyProj\Projects\OpenCloverTest\src\main\java\OpenClover.java" name="OpenClover.java">
<metrics coveredelements="0" coveredconditionals="0" complexity="1" loc="7" coveredmethods="0" methods="1" elements="4" classes="1" ncloc="7" statements="3" conditionals="0" coveredstatements="0"/>
<class name="OpenClover">
<metrics coveredelements="0" coveredconditionals="0" complexity="1" coveredmethods="0" methods="1" elements="4" statements="3" conditionals="0" coveredstatements="0"/>
</class>
<line complexity="1" visibility="public" signature="main(String[]) : void" num="2" count="0" type="method"/>
<line num="3" count="0" type="stmt"/>
<line num="4" count="0" type="stmt"/>
<line num="5" count="0" type="stmt"/>
</file>
</package>
</project>
<testproject name="OpenCloverTest 1.0-SNAPSHOT" timestamp="1586952298327">
<metrics coveredelements="5" complexity="2" loc="16" methods="2" classes="1" statements="3" packages="1" coveredconditionals="0" coveredmethods="2" elements="5" ncloc="14" files="1" conditionals="0" coveredstatements="3"/>
<package name="default-pkg">
<metrics coveredelements="5" complexity="2" loc="16" methods="2" classes="1" statements="3" coveredconditionals="0" coveredmethods="2" elements="5" ncloc="14" files="1" conditionals="0" coveredstatements="3"/>
<file path="F:MyProj\Projects\OpenCloverTest\src\test\java\Test.java" name="Test.java">
<metrics coveredelements="5" coveredconditionals="0" complexity="2" loc="16" coveredmethods="2" methods="2" elements="5" classes="1" ncloc="14" statements="3" conditionals="0" coveredstatements="3"/>
<class name="Test">
<metrics coveredelements="5" complexity="2" methods="2" testruns="2" statements="3" coveredconditionals="0" coveredmethods="2" elements="5" testfailures="0" testduration="0.008" conditionals="0" coveredstatements="3" testpasses="2"/>
</class>
<line complexity="1" visibility="public" signature="testSum() : void" num="6" testsuccess="true" count="1" testduration="0.008" type="method"/>
<line num="9" count="1" type="stmt"/>
<line num="10" count="1" type="stmt"/>
<line complexity="1" visibility="public" signature="testMulti() : void" num="12" testsuccess="true" count="1" testduration="0.0" type="method"/>
<line num="14" count="1" type="stmt"/>
</file>
</package>
</testproject>
</coverage>
So from the XML data how can I tell which test covered which method?
EDIT: Added Test.java and Calculator.java
Calculator.java
public class Calculator {
public int sum(int a, int b){
if(a > b) {
return a + a + b;
}
return a+b;
}
public int mulitpliy(int a , int b){
return a*b;
}
public int division(int a, int b){
int c = a+b;
int d = a-b;
int f = a*d;
return a / b;
}
}
Test.java
import static org.junit.Assert.assertEquals;
public class Test {
Calculator calc = new Calculator();
@org.junit.Test
public void testSum(){
assertEquals(10,calc.sum(5,5));
assertEquals(25,calc.sum(10,5));
}
@org.junit.Test
public void testMulti(){
assertEquals(10,calc.mulitpliy(5,2));
}
}
Example output based on answer by @Hades:
Method name :: signature="sum(int,int) : int"
Covered line :: 6 covered by: signature="testSum() : void"
UncoveredLines :: 0
Unfortunately OpenClover does not print per-test coverage information in the XML report. Extracting this information from the HTML report is not easy either.
I suggest to have a look at the SnapshotPrinter utility, it prints information for files and classes:
https://openclover.org/doc/manual/latest/hacking--measuring-per-test-coverage-for-manual-tests.html
As OpenClover is open-source, you could extend the SnapshotPrinter to get information for individual methods as well, see:
Alternatively, you could read this information from the clover.db database directly. Please have a look at my answer to a similar question here:
Cheers