{"id":585,"date":"2014-02-25T01:53:48","date_gmt":"2014-02-25T01:53:48","guid":{"rendered":"http:\/\/choudhury.com\/blog\/?p=585"},"modified":"2018-12-20T01:06:33","modified_gmt":"2018-12-20T01:06:33","slug":"enforcing-minimum-code-coverage","status":"publish","type":"post","link":"https:\/\/choudhury.com\/blog\/2014\/02\/25\/enforcing-minimum-code-coverage\/","title":{"rendered":"Enforcing Minimum Code Coverage"},"content":{"rendered":"<p>If you want to enforce minimum code coverage check, <a title=\"JaCoCo\" href=\"http:\/\/www.eclemma.org\/jacoco\/\">JaCoCo <\/a>worked really in the projects that I&#8217;ve worked on so far.<\/p>\n<p>JaCoCo works as agent (there is another option where it can do <a href=\"http:\/\/www.eclemma.org\/jacoco\/trunk\/doc\/offline.html\">offline instrumentation<\/a>). The prepare-agent goal sets up the &#8220;jacocoProperty&#8221; property to setup JaCoCo as agent on the the surefire argLine (so it will only work if sure-fire is configured to run your unit tests in forked process)<\/p>\n<p>Here is basic <a title=\"GitHub Project Code Coverage Checks\" href=\"https:\/\/github.com\/muminc\/coverage-check-example\">maven project<\/a> that demonstrates how to check minimum line and branch coverage of 80% is met.<\/p>\n<p><strong>Prepare Agent Goal<\/strong><\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">&lt;plugin&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;org.jacoco&lt;\/groupId&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;jacoco-maven-plugin&lt;\/artifactId&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;version&gt;0.8.2&lt;\/version&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;executions&gt;<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;!-- &nbsp;(1) &nbsp;Prepare agent runs in the init phase, it setups the jacocoProperty, &nbsp;so we can insert this to the maven sure fire argLine and get to run jacoco as agent --&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;execution&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;id&gt;prepare-agent&lt;\/id&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;goals&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;goal&gt;prepare-agent&lt;\/goal&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/goals&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;propertyName&gt;jacocoArgLine&lt;\/propertyName&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;includes&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;include&gt;com.choudhury.codecoverage.*&lt;\/include&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/includes&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/execution&gt;<\/div><\/div>\n<p><strong>SureFire Plugin Argline<\/strong><\/p>\n<p>We run sure fire and we add the &#8220;jacocoProperty&#8221; as part of the argLine<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">&nbsp;&lt;plugin&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;maven-surefire-plugin&lt;\/artifactId&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;version&gt;2.22.1&lt;\/version&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;!-- (2) &nbsp;setup the argLine and run the unit tests. &nbsp; **NOTE the &quot;jacocArgeLine&quot; property was configured the &quot;prepare-agent&quot; goal of Jacoco &nbsp;(see below) --&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;argLine&gt;${jacocoArgLine} -Xmx256m&lt;\/argLine&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &lt;\/plugin&gt;<\/div><\/div>\n<p>After the forked sure fire process is has completed it write the jacoco.exec file in the target file. This file is required for both the &#8220;check&#8221; and &#8220;report&#8221; JaCoCo goals.<\/p>\n<p><a href=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_coverage_file.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_coverage_file.png\" alt=\"jacoco_coverage_file\" width=\"884\" height=\"327\" class=\"alignnone size-full wp-image-641\" srcset=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_coverage_file.png 884w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_coverage_file-300x110.png 300w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/p>\n<p><strong>Check Goal<\/strong><br \/>\nIn verify phase, we execute the <a href=\"http:\/\/www.eclemma.org\/jacoco\/trunk\/doc\/check-mojo.html\">check <\/a>goal of JaCoCo<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;!-- &nbsp;(3) the check goal by default runs in the verify phase, we want to fail the build if mimimum code coverage checks aren't met --&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;execution&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;id&gt;check&lt;\/id&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;goals&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;goal&gt;check&lt;\/goal&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/goals&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;rules&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;!-- All classes must have 80% line and branch coverage . Note we use 2 d.p so that we get can any check failure messages reported to 2 d.p &nbsp;--&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;rule &gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;element&gt;CLASS&lt;\/element&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;limits&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;limit &gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;counter&gt;LINE&lt;\/counter&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;COVEREDRATIO&lt;\/value&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;minimum&gt;0.80&lt;\/minimum&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/limit&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;limit &gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;counter&gt;BRANCH&lt;\/counter&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;COVEREDRATIO&lt;\/value&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;minimum&gt;0.80&lt;\/minimum&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/limit&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/limits&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;excludes&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;exclude&gt;com.choudhury.codecoverage.Bye&lt;\/exclude&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/excludes&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/rule&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/rules&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/configuration&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/execution&gt;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/executions&gt;<\/div><\/div>\n<p><strong>Example Project<\/strong><\/p>\n<p>Example maven project can be found <a title=\"GitHub Project Code Coverage Checks\" href=\"https:\/\/github.com\/muminc\/coverage-check-example\">here<\/a><\/p>\n<p>With the example project, when we run &#8220;mvn clean install&#8221; we expect to fail on code coverage checks.<\/p>\n<p>To confirm that Jacoco agent is correctly being appended to the Java argLine for maven SureFire plugin, temporarily put a long enough pause in the Unit Test (and whilst the Unit Test are running)  launch <strong>jvisualvm <\/strong>to check that jacoco is correctly setup as an agent.<\/p>\n<p><a href=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_run_as_agent.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_run_as_agent.png\" alt=\"jacoco_run_as_agent\" width=\"1441\" height=\"600\" class=\"alignnone size-full wp-image-601\" srcset=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_run_as_agent.png 1441w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_run_as_agent-300x124.png 300w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_run_as_agent-1024x426.png 1024w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_failed.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_failed.png\" alt=\"min_check_failed\" width=\"1317\" height=\"383\" class=\"alignnone size-full wp-image-603\" srcset=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_failed.png 1317w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_failed-300x87.png 300w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_failed-1024x297.png 1024w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/p>\n<p>If we update the HelloTest to test the missed branch and re-run &#8220;mvn clean install&#8221; we should see the lines <strong>&#8220;All Coverage checks have been met&#8221;<\/strong> to appear and the the build should pass  \ud83d\ude42<\/p>\n<p><a href=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_passed.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_passed.png\" alt=\"min_check_passed\" width=\"1317\" height=\"383\" class=\"alignnone size-full wp-image-605\" srcset=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_passed.png 1317w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_passed-300x87.png 300w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/min_check_passed-1024x297.png 1024w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/p>\n<p><strong>JaCoCo Code Coverage Reports<\/strong><\/p>\n<p>Another nice feature of JaCoCo maven plugin is the <a href=\"http:\/\/www.eclemma.org\/jacoco\/trunk\/doc\/report-mojo.html\">report<\/a> goal allowing you to see which lines have been covered by your tests.<\/p>\n<p>Execute the report goal of the JaCoCo maven plugin<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">mvn jacoco:report<\/div><\/div>\n<p>(<strong>Note : <\/strong> this reads the jacoco.exec file in your target folder,  do make sure it&#8217;s present when you run this goal, otherwise you will get no reports produced).<\/p>\n<p>The report goal should produce the html files under target\/site\/jacoco folder.<\/p>\n<p><a href=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports.jpg\" alt=\"\" width=\"1104\" height=\"541\" class=\"alignnone size-full wp-image-684\" srcset=\"https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports.jpg 1104w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports-300x147.jpg 300w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports-768x376.jpg 768w, https:\/\/choudhury.com\/blog\/wp-content\/uploads\/2014\/02\/jacoco_html_reports-1024x502.jpg 1024w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/p>\n<ul>\n<li>Green shows the covered lines<\/li>\n<li>Yellow shows partially covered branches (you can hover over the diamond icon to get tooltip of how many branches covered)<\/li>\n<li>Red is the missed lines.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>If you want to enforce minimum code coverage check, JaCoCo worked really in the projects that I&#8217;ve worked on so far. JaCoCo works as agent (there is another option where it can do offline instrumentation). The prepare-agent goal sets up the &#8220;jacocoProperty&#8221; property to setup JaCoCo as agent on the the surefire argLine (so it &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/choudhury.com\/blog\/2014\/02\/25\/enforcing-minimum-code-coverage\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Enforcing Minimum Code Coverage&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,3,12],"tags":[],"class_list":["post-585","post","type-post","status-publish","format-standard","hentry","category-code-quality","category-java","category-testing"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/585","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/comments?post=585"}],"version-history":[{"count":33,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/585\/revisions"}],"predecessor-version":[{"id":763,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/585\/revisions\/763"}],"wp:attachment":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/media?parent=585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/categories?post=585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/tags?post=585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}