-
Notifications
You must be signed in to change notification settings - Fork 75
Home
This plugin serves as API to integrate and publish multiple coverage report types. More information see https://jenkins.io/projects/gsoc/2018/code-coverage-api-plugin/.
You need to do two things to implement Code Coverage API plugin:
- convert other coverage reports to our report format.
- implement an extension point, and return the converted report.
If you want to implement a new plugin, you need to convert other coverage reports format to our XML format (or its equivalent java org.w3c.Document
object), it is a format simplified by Cobertura report.
You can use two methods to generate a report.
You can put line elements in other elements (like method, class and file), so the parent elements and the higher level elements will have coverage information calculated by those line elements.
The format of line element:
<line number="{lineNumber}" hits="{hitNumber}" branch="{true|false}" (optional)condition-coverage="percentage%(coveredBranch/branchNumber)">
.
If hits
is set a value larger than 0, this line will be view as a covered line. If branch
is set to true, it means it has branch and you need to set condition coverage to condition-coverage
in a format like 50%(1/2)
.
We calculate line coverage by following the below rules:
- Any element that contains line elements will have a coverage ratio value calculated by its child line elements.
- Any element that contains other child elements will have a coverage ratio value calculated by its child elements coverage ratio.
- If an element has both line elements and other type elements, the ratio value calculated by other child coverage elements will override the one by line elements.
<report name="jacoco">
<group name="project">
<package name="hudson/plugins/cobertura">
<file name="hudson/plugins/cobertura/IOUtils.java">
<class name="hudson/plugins/cobertura/IOUtils">
<method name="closeQuietly" signature="(Ljava/io/Closeable;)V">
<line branch="true" condition-coverage="50% (1/2)" hits="1" number="16"/>
<line branch="false" hits="1" number="18"/>
<line branch="false" hits="0" number="19"/>
<line branch="false" hits="1" number="20"/>
<line branch="false" hits="1" number="22"/>
</method>
</class>
</file>
</package>
</group>
</report>
You can also add coverage information as attribute to element. In such case, plugin will not able to support souce code navigation due to the lacking information of line number.
<report name="jacoco">
<group name="project">
<package attr-mode="true" br-covered="216" br-missed="277" instruction-covered="2341" instruction-missed="2622"
line-covered="532" line-missed="586" name="hudson/plugins/cobertura">
<file name="MavenCoberturaPublisher.java">
<class attr-mode="true" br-covered="0" br-missed="2" instruction-covered="0" instruction-missed="57"
line-covered="0" line-missed="16"
name="hudson/plugins/cobertura/MavenCoberturaPublisher$MavenCoberturaActionAdder">
<method attr-mode="true" instruction-covered="0" instruction-missed="6" line-covered="0"
line-missed="3" name="<init>" signature="(Lhudson/model/BuildListener;)V"/>
<method attr-mode="true" br-covered="0" br-missed="2" instruction-covered="0"
instruction-missed="51" line-covered="0" line-missed="13" name="call"
signature="(Lhudson/maven/MavenBuild;)Ljava/lang/Boolean;"/>
</class>
</file>
</package>
</group>
</report>
You can take a look at the implementation in JacocoReportAdapter.
For other elements, we only need two values - element type, element name. If you use the CoverageParser
implementation we provide, we will use element tag as the type and name attribute as the name. You can also implement CoverageParser
to customize it.
If you use element types (like function
, module
) that we don't support, you need to register CoverageElement
s and implement a simple parser. See llvm-cov Plugin to get more details.
you need implement CoverageReportAdapter extension point to implement a coverage api plugin.
For example, by using the provided abstract layer, we can implement JaCoCo like this:
public final class JacocoReportAdapter extends JavaXMLCoverageReportAdapter {
@DataBoundConstructor
public JacocoReportAdapter(String path) {
super(path);
}
@Override
public String getXSL() {
return "jacoco-to-standard.xsl";
}
@Override
public String getXSD() {
return null;
}
@Symbol("jacoco")
@Extension
public static final class JacocoReportAdapterDescriptor extends JavaCoverageReportAdapterDescriptor<CoverageReportAdapter> {
public JacocoReportAdapterDescriptor() {
super(JacocoReportAdapter.class, "jacoco");
}
}
}
All we need is to extend an abstract layer for XML-based Java report and provide an XSL file to convert the report to our standard format.