{"id":604,"date":"2011-10-25T20:43:00","date_gmt":"2011-10-25T20:43:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/code-coverage-with-unit-integration-tests.html"},"modified":"2012-10-21T20:24:19","modified_gmt":"2012-10-21T20:24:19","slug":"code-coverage-with-unit-integration","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html","title":{"rendered":"Code coverage with unit &amp; integration tests"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated into my maven build, with code coverage reports so I could get an idea of areas with insufficient test coverage. Rather than just publish the source code for the project, I\u2019ve put together a simple example to demonstrate how I got all this setup; so if you\u2019re looking to integrate <a href=\"http:\/\/maven.apache.org\/\">maven<\/a>, <a href=\"http:\/\/junit.org\/\">junit<\/a>, <a href=\"http:\/\/code.google.com\/p\/selenium\/?redir=1\">webdriver <\/a>(now selenium) and <a href=\"http:\/\/emma.sourceforge.net\/\">emma <\/a>&#8211; read on to find out how I went about it.<\/p>\n<p>First off, all the source code for this is available on github: <a href=\"https:\/\/github.com\/activelylazy\/coverage-example\">https:\/\/github.com\/activelylazy\/coverage-example<\/a>. I\u2019ll show key snippets, but obviously there\u2019s lots of detail omitted that (hopefully) isn\u2019t relevant.<\/p>\n<h1>The Example App<\/h1>\n<p>Rather than break with tradition, the example application is a simple, if slightly contrived, hello world:<\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/activelylazy.files.wordpress.com\/2010\/11\/helloworld.png\"><img decoding=\"async\" alt=\"\" class=\"alignleft size-full wp-image-288\" height=\"373\" src=\"http:\/\/activelylazy.files.wordpress.com\/2010\/11\/helloworld.png?w=500&amp;h=373\" width=\"500\" \/><\/a><\/div>\n<div class=\"separator\" style=\"clear: both;text-align: center\">\n<\/div>\n<h2>How It Works<\/h2>\n<p>The start page is a simple link to the hello world page:<\/p>\n<pre class=\"brush: xml;\">&lt;h1&gt;Example app&lt;\/h1&gt;\r\n&lt;p&gt;See the &lt;a id=\"messageLink\" href=\"helloWorld.html\"&gt;message&lt;\/a&gt;&lt;\/p&gt;\r\n<\/pre>\n<p>The hello world page just displays the message:<\/p>\n<pre class=\"brush: xml;\">&lt;h1&gt;Example app&lt;\/h1&gt;\r\n&lt;p id=\"message\"&gt;&lt;c:out value=\"${message}\"\/&gt;&lt;\/p&gt;\r\n<\/pre>\n<p>The hello world controller renders the view, passing in the message:<\/p>\n<pre class=\"brush: java;\">public class HelloWorldController extends ParameterizableViewController {\r\n    \/\/ Our message factory\r\n    private MessageFactory messageFactory;\r\n    @Override\r\n    protected ModelAndView handleRequestInternal(HttpServletRequest request,\r\n        HttpServletResponse response) throws Exception {\r\n        \/\/ Get the success view\r\n        ModelAndView mav = super.handleRequestInternal(request, response);\r\n        \/\/ Add our message\r\n        mav.addObject(\"message\",messageFactory.createMessage());\r\n        return mav;\r\n    }\r\n    @Autowired\r\n    public void setMessageFactory(MessageFactory messageFactory) {\r\n        this.messageFactory = messageFactory;\r\n    }\r\n}<\/pre>\n<p>Finally the MessageFactory simply returns the hard-coded message:<\/p>\n<pre class=\"brush: java;\">public String createMessage() {\r\n    return \"Hello world\";\r\n}\r\n<\/pre>\n<h2>The unit test<\/h2>\n<p>We define a simple unit test to verify that the MessageFactory behaves as expected:<\/p>\n<pre class=\"brush: java;\">public class MessageFactoryTest {\r\n    \/\/ The message factory\r\n    private MessageFactory messageFactory;\r\n    @Test\r\n    public void testCreateMessage() {\r\n        assertEquals(\"Hello world\",messageFactory.createMessage());\r\n    }\r\n    @Autowired\r\n    public void setMessageFactory(MessageFactory messageFactory) {\r\n        this.messageFactory = messageFactory;\r\n    }\r\n}\r\n<\/pre>\n<h2>Build<\/h2>\n<p>A basic maven pom file is sufficient to build this and run the unit test. At this point we have a working app, with a unit test for the core functionality (such as it is) that we can build and run.<\/p>\n<pre class=\"brush: xml;\">&lt;project&gt;\r\n    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n    &lt;groupId&gt;com.example&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;helloworld&lt;\/artifactId&gt;\r\n    &lt;packaging&gt;war&lt;\/packaging&gt;\r\n    &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\r\n    &lt;name&gt;helloworld Maven Webapp&lt;\/name&gt;\r\n    &lt;build&gt;\r\n        &lt;finalName&gt;helloworld&lt;\/finalName&gt;\r\n    &lt;\/build&gt;\r\n    &lt;dependencies&gt;\r\n        ...omitted...\r\n    &lt;\/dependencies&gt;\r\n&lt;\/project&gt;\r\n<\/pre>\n<h1>Code Coverage<\/h1>\n<p>Now let\u2019s integrate Emma so we can get some code coverage reports. First, we define a new Maven profile, this allows us to control whether or not we use emma on any given build.<\/p>\n<pre class=\"brush: xml;\">&lt;profile&gt;\r\n    &lt;id&gt;with-emma&lt;\/id&gt;\r\n    &lt;build&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;emma-maven-plugin&lt;\/artifactId&gt;\r\n                &lt;inherited&gt;true&lt;\/inherited&gt;\r\n                &lt;executions&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;id&gt;instrument&lt;\/id&gt;\r\n                        &lt;phase&gt;process-test-classes&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;instrument&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                    &lt;\/execution&gt;\r\n                &lt;\/executions&gt;\r\n            &lt;\/plugin&gt;\r\n        &lt;\/plugins&gt;\r\n    &lt;\/build&gt;\r\n&lt;\/profile&gt;\r\n<\/pre>\n<p>This simply invokes the \u201cinstrument\u201d goal during the Maven \u201cprocess-test-classes\u201d phase; i.e. once we\u2019ve compiled our class files, use emma to instrument them. We can run this by invoking maven with the new profile:<\/p>\n<pre class=\"brush: bash; gutter: false;\">mvn clean install -Pwith-emma\r\n<\/pre>\n<p>Once the build has completed, we can run Emma to generate code coverage reports:<br \/>\nOn Windows:<\/p>\n<pre class=\"brush: bash; gutter: false;\">java -cp %USERPROFILE%\/.m2\/repository\/emma\/emma\/2.0.5312\/emma-2.0.5312.jar emma report -r xml,html -in coverage.ec -in target\/coverage.em\r\n<\/pre>\n<p>On Linux:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: bash; gutter: false;\">java -cp ~\/.m2\/repository\/emma\/emma\/2.0.5312\/emma-2.0.5312.jar emma report -r xml,html -in coverage.ec -in target\/coverage.em\r\n<\/pre>\n<p>We can now view the HTML coverage report in coverage\/index.html. At this point, it shows we have 50% test coverage (by classes). MessageFactory is fully covered, but the HelloWorldController doesn\u2019t have any tests at all.<\/p>\n<h1>Integration Test<\/h1>\n<p>To test our controller and JSP, we\u2019ll use WebDriver to create a simple integration test; this is a JUnit test that happens to launch a browser.<\/p>\n<pre class=\"brush: java;\">public class HelloWorldIntegrationTest {\r\n    \/\/ The webdriver\r\n    private static WebDriver driver;\r\n    @BeforeClass\r\n    public static void initWebDriver() {\r\n        driver = new FirefoxDriver();\r\n    }\r\n    @AfterClass\r\n    public static void stopSeleniumClent() {\r\n        try {\r\n            driver.close();\r\n            driver.quit();\r\n        } catch( Throwable t ) {\r\n            \/\/ Catch error &amp; log, not critical for tests\r\n            System.err.println(\"Error stopping driver: \"+t.getMessage());\r\n            t.printStackTrace(System.err);\r\n        }\r\n    }\r\n    @Test\r\n    public void testHelloWorld() {\r\n        \/\/ Start from the homepage\r\n        driver.get(\"http:\/\/localhost:9080\/helloworld\/\");\r\n        HomePage homePage = new HomePage(driver);\r\n        HelloWorldPage helloWorldPage = homePage.clickMessageLink();\r\n        assertEquals(\"Hello world\",helloWorldPage.getMessage());\r\n    }\r\n}\r\n<\/pre>\n<p>Lines 4-18 simply start Web Driver before the test and shut it down (closing the browser window) once the test is finished.<br \/>\nOn line 22 we navigate to the homepage with a hard-coded URL.<br \/>\nOn line 23 we initialise our Web Driver <a href=\"http:\/\/code.google.com\/p\/selenium\/wiki\/PageObjects\">page object<\/a> for the homepage. This encapsulates all the details of how the page works, allowing the test to interact with the page functionally, without worrying about the mechanics (which elements to use etc).<br \/>\nOn line 24 we use the homepage object to click the \u201cmessage\u201d link; this navigates to the hello world page.<br \/>\nOn line 25 we confirm that the message shown on the hello world page is what we expect.<br \/>\nNote: I\u2019m using page objects to separate <em>test specification<\/em> (what to do) from <em>test implementation<\/em> (how to do it). For more on why this is important see <a href=\"http:\/\/www.cheezyworld.com\/2010\/11\/09\/ui-tests-not-brittle\/\">keeping tests from being brittle<\/a>.<\/p>\n<h2>Homepage<\/h2>\n<p>The homepage object is pretty simple:<\/p>\n<pre class=\"brush: java;\">public HelloWorldPage clickMessageLink() {\r\n    driver.findElement(By.id(\"messageLink\")).click();\r\n    return new HelloWorldPage(driver);\r\n}\r\n<\/pre>\n<h2>HelloWorldPage<\/h2>\n<p>The hello world page is equally simple:<\/p>\n<pre class=\"brush: java;\">public String getMessage() {\r\n    return driver.findElement(By.id(\"message\")).getText();\r\n}\r\n<\/pre>\n<h2>Running the Integration Test<\/h2>\n<p>To run the integration test during our Maven build we need to make a few changes. First, we need to exclude integration tests from the unit test phase:<\/p>\n<pre class=\"brush: xml; highlight: [8];\">&lt;plugin&gt;\r\n    &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;maven-surefire-plugin&lt;\/artifactId&gt;\r\n    ...\r\n    &lt;configuration&gt;\r\n        ...\r\n        &lt;excludes&gt;\r\n            &lt;exclude&gt;**\/*IntegrationTest.java&lt;\/exclude&gt;\r\n            &lt;exclude&gt;**\/common\/*&lt;\/exclude&gt;\r\n        &lt;\/excludes&gt;\r\n    &lt;\/configuration&gt;\r\n&lt;\/plugin&gt;\r\n<\/pre>\n<p>Then we define a new profile, so we can optionally run integration tests:<\/p>\n<pre class=\"brush: xml;\">&lt;profile&gt;\r\n    &lt;id&gt;with-integration-tests&lt;\/id&gt;\r\n    &lt;build&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;org.mortbay.jetty&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;maven-jetty-plugin&lt;\/artifactId&gt;\r\n                &lt;version&gt;6.1.22&lt;\/version&gt;\r\n                &lt;configuration&gt;\r\n                    &lt;scanIntervalSeconds&gt;5&lt;\/scanIntervalSeconds&gt;\r\n                    &lt;stopPort&gt;9966&lt;\/stopPort&gt;\r\n                    &lt;stopKey&gt;foo&lt;\/stopKey&gt;\r\n                    &lt;connectors&gt;\r\n                        &lt;connector implementation=\"org.mortbay.jetty.nio.SelectChannelConnector\"&gt;\r\n                            &lt;port&gt;9080&lt;\/port&gt;\r\n                            &lt;maxIdleTime&gt;60000&lt;\/maxIdleTime&gt;\r\n                        &lt;\/connector&gt;\r\n                    &lt;\/connectors&gt;\r\n                &lt;\/configuration&gt;\r\n                &lt;executions&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;id&gt;start-jetty&lt;\/id&gt;\r\n                        &lt;phase&gt;pre-integration-test&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;run&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                        &lt;configuration&gt;\r\n                            &lt;daemon&gt;true&lt;\/daemon&gt;\r\n                        &lt;\/configuration&gt;\r\n                    &lt;\/execution&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;id&gt;stop-jetty&lt;\/id&gt;\r\n                        &lt;phase&gt;post-integration-test&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;stop&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                    &lt;\/execution&gt;\r\n                &lt;\/executions&gt;\r\n            &lt;\/plugin&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;maven-surefire-plugin&lt;\/artifactId&gt;\r\n                &lt;version&gt;2.5&lt;\/version&gt;\r\n                &lt;inherited&gt;true&lt;\/inherited&gt;\r\n                &lt;executions&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;id&gt;integration-tests&lt;\/id&gt;\r\n                        &lt;phase&gt;integration-test&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;test&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                        &lt;configuration&gt;\r\n                            &lt;excludes&gt;\r\n                                &lt;exclude&gt;**\/common\/*&lt;\/exclude&gt;\r\n                            &lt;\/excludes&gt;\r\n                            &lt;includes&gt;\r\n                                &lt;include&gt;**\/*IntegrationTest.java&lt;\/include&gt;\r\n                            &lt;\/includes&gt;\r\n                        &lt;\/configuration&gt;\r\n                    &lt;\/execution&gt;\r\n                &lt;\/executions&gt;\r\n            &lt;\/plugin&gt;\r\n        &lt;\/plugins&gt;\r\n    &lt;\/build&gt;\r\n&lt;\/profile&gt;\r\n<\/pre>\n<div class=\"mcePaste\" style=\"height: 1px;overflow: hidden;width: 1px\">&lt;profile&gt;<\/p>\n<p>&lt;id&gt;with-integration-tests&lt;\/id&gt;<\/p>\n<p>&lt;build&gt;<\/p>\n<p>&lt;plugins&gt;<\/p>\n<p>&lt;plugin&gt;<\/p>\n<p>&lt;groupId&gt;org.mortbay.jetty&lt;\/groupId&gt;<\/p>\n<p>&lt;artifactId&gt;maven-jetty-plugin&lt;\/artifactId&gt;<\/p>\n<p>&lt;version&gt;6.1.22&lt;\/version&gt;<\/p>\n<p>&lt;configuration&gt;<\/p>\n<p>&lt;scanIntervalSeconds&gt;5&lt;\/scanIntervalSeconds&gt;<\/p>\n<p>&lt;stopPort&gt;9966&lt;\/stopPort&gt;<\/p>\n<p>&lt;stopKey&gt;foo&lt;\/stopKey&gt;<\/p>\n<p>&lt;connectors&gt;<\/p>\n<p>&lt;connector implementation=\u201dorg.mortbay.jetty.nio.SelectChannelConnector\u201d&gt;<\/p>\n<p>&lt;port&gt;${test.server.port}&lt;\/port&gt;<\/p>\n<p>&lt;maxIdleTime&gt;60000&lt;\/maxIdleTime&gt;<\/p>\n<p>&lt;\/connector&gt;<\/p>\n<p>&lt;\/connectors&gt;<\/p>\n<p>&lt;\/configuration&gt;<\/p>\n<p>&lt;executions&gt;<\/p>\n<p>&lt;execution&gt;<\/p>\n<p>&lt;id&gt;start-jetty&lt;\/id&gt;<\/p>\n<p>&lt;phase&gt;pre-integration-test&lt;\/phase&gt;<\/p>\n<p>&lt;goals&gt;<\/p>\n<p>&lt;goal&gt;run&lt;\/goal&gt;<\/p>\n<p>&lt;\/goals&gt;<\/p>\n<p>&lt;configuration&gt;<\/p>\n<p>&lt;daemon&gt;true&lt;\/daemon&gt;<\/p>\n<p>&lt;\/configuration&gt;<\/p>\n<p>&lt;\/execution&gt;<\/p>\n<p>&lt;execution&gt;<\/p>\n<p>&lt;id&gt;stop-jetty&lt;\/id&gt;<\/p>\n<p>&lt;phase&gt;post-integration-test&lt;\/phase&gt;<\/p>\n<p>&lt;goals&gt;<\/p>\n<p>&lt;goal&gt;stop&lt;\/goal&gt;<\/p>\n<p>&lt;\/goals&gt;<\/p>\n<p>&lt;\/execution&gt;<\/p>\n<p>&lt;\/executions&gt;<\/p>\n<p>&lt;\/plugin&gt;<\/p>\n<p>&lt;plugin&gt;<\/p>\n<p>&lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;<\/p>\n<p>&lt;artifactId&gt;maven-surefire-plugin&lt;\/artifactId&gt;<\/p>\n<p>&lt;version&gt;2.5&lt;\/version&gt;<\/p>\n<p>&lt;inherited&gt;true&lt;\/inherited&gt;<\/p>\n<p>&lt;executions&gt;<\/p>\n<p>&lt;execution&gt;<\/p>\n<p>&lt;id&gt;integration-tests&lt;\/id&gt;<\/p>\n<p>&lt;phase&gt;integration-test&lt;\/phase&gt;<\/p>\n<p>&lt;goals&gt;<\/p>\n<p>&lt;goal&gt;test&lt;\/goal&gt;<\/p>\n<p>&lt;\/goals&gt;<\/p>\n<p>&lt;configuration&gt;<\/p>\n<p>&lt;excludes&gt;<\/p>\n<p>&lt;exclude&gt;**\/common\/*&lt;\/exclude&gt;<\/p>\n<p>&lt;\/excludes&gt;<\/p>\n<p>&lt;includes&gt;<\/p>\n<p>&lt;include&gt;**\/*IntegrationTest.java&lt;\/include&gt;<\/p>\n<p>&lt;\/includes&gt;<\/p>\n<p>&lt;\/configuration&gt;<\/p>\n<p>&lt;\/execution&gt;<\/p>\n<p>&lt;\/executions&gt;<\/p>\n<p>&lt;\/plugin&gt;<\/p>\n<p>&lt;\/plugins&gt;<\/p>\n<p>&lt;\/build&gt;<\/p>\n<p>&lt;\/profile&gt;<\/p>\n<\/div>\n<p>This may look complex, but really we\u2019re just configuring jetty to run while we run our integration tests; then configuring how to run the integration tests themselves.<br \/>\nIn lines 9-19 configure jetty \u2013 the port to run on and how to stop it.<br \/>\nLines 21-30 configure jetty to run during the \u201cpre-integration-test\u201d phase of the maven build.<br \/>\nLines 31-37 configure jetty to be stopped during the \u201cpost-integration-test\u201d phase of the maven build.<br \/>\nIn lines 40-62 we use the maven-surefire-plugin again, this time to run during the \u201cintegration-test\u201d phase of the build, only running our integration test classes.<\/p>\n<p>We can run this build with:<\/p>\n<pre class=\"brush: bash; gutter: false;\">mvn clean install -Pwith-emma -Pwith-integration-tests\r\n<\/pre>\n<p>This will build everything, run the unit tests, build the war, fire up jetty to host the war, run our integration tests (you\u2019ll see a firefox window popup while the rest runs) then shut down jetty. Because the war is built with instrumented classes, Emma also tracks code coverage while we run our integration tests.<\/p>\n<p>We can now build our application, running unit tests and integration tests, gathering combined code coverage reports. If we re-run the emma report and check code coverage we now see we have 100% test coverage \u2013 since the controller is also being covered through tests.<\/p>\n<h1>Issues<\/h1>\n<p>What are the outstanding issues with this, what further extensions can be made?<\/p>\n<ul>\n<li>The build produces an instrumented WAR \u2013 this means you need to run a second build, without emma, to get a production-ready build.<\/li>\n<li>The integration test hard-codes the port that Jetty is configured to start on; meaning the tests can\u2019t be run directly within Eclipse. It is possible to pass this port in, defaulting to say, 8080, so that integration tests can be run seemlessly within Eclipse as well via the maven build<\/li>\n<li>When running on your build server you probably don\u2019t want Firefox popping up at random (if X is even installed); so running <a href=\"http:\/\/www.xfree86.org\/4.0.1\/Xvfb.1.html\">xvfb<\/a> is a good idea. It is possible to setup maven to start &amp; stop xvfb before &amp; after the integration tests.<\/li>\n<\/ul>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/blog.activelylazy.co.uk\/2010\/11\/11\/code-coverage-with-unit-integration-tests\/\">Code coverage with unit &amp; integration tests<\/a> and from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a>&nbsp;<a href=\"http:\/\/blog.activelylazy.co.uk\/about\/\">Dave<\/a> at <a href=\"http:\/\/blog.activelylazy.co.uk\/\">Actively Lazy<\/a>&nbsp;blog<\/p>\n<div style=\"margin: 0px\"><strong><i>Related Articles :<\/i><\/strong><\/div>\n<ul>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/services-practices-tools-that-should.html\">Services, practices &amp; tools that should exist in any software development house, part 1<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/services-practices-tools-that-should_18.html\">Services, practices &amp; tools that should exist in any software development house, part 2<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/this-comes-before-your-business-logic.html\">This comes BEFORE your business logic!<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/how-many-bugs-do-you-have-in-your-code.html\">How many bugs do you have in your code?<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/02\/using-findbugs-to-produce-substantially.html\">Using FindBugs to produce substantially less buggy code<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/java-tools-source-code-optimization-and.html\">Java Tools: Source Code Optimization and Analysis<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/12\/things-every-programmer-should-know.html\">Things Every Programmer Should Know<\/a>&nbsp;<\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/04\/automated-tests-boost-development-speed.html\">Why Automated Tests Boost Your Development Speed<\/a>&nbsp; <\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated into my maven build, with code coverage reports so I could get an idea of areas with insufficient test coverage. Rather than just publish the source &hellip;<\/p>\n","protected":false},"author":97,"featured_media":231,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[288,274,287],"class_list":["post-604","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-emma","tag-junit","tag-selenium"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Code coverage with unit &amp; integration tests - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Code coverage with unit &amp; integration tests - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-10-25T20:43:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:24:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"David Green\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/activelylazy\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"David Green\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html\"},\"author\":{\"name\":\"David Green\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/4c77ca256cd47f1e3a9dbe6bd23c3ee7\"},\"headline\":\"Code coverage with unit &amp; integration tests\",\"datePublished\":\"2011-10-25T20:43:00+00:00\",\"dateModified\":\"2012-10-21T20:24:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html\"},\"wordCount\":1340,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/selenium-logo.jpg\",\"keywords\":[\"EMMA\",\"JUnit\",\"Selenium\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html\",\"name\":\"Code coverage with unit &amp; integration tests - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/selenium-logo.jpg\",\"datePublished\":\"2011-10-25T20:43:00+00:00\",\"dateModified\":\"2012-10-21T20:24:19+00:00\",\"description\":\"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/selenium-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/selenium-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/code-coverage-with-unit-integration.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Code coverage with unit &amp; integration tests\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/4c77ca256cd47f1e3a9dbe6bd23c3ee7\",\"name\":\"David Green\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g\",\"caption\":\"David Green\"},\"description\":\"David Green is a developer and aspiring software craftsman. He has been programming for 20 years but only getting paid to do it for the last 10; in that time he has worked for a variety of companies from small start-ups to global enterprises.\",\"sameAs\":[\"http:\\\/\\\/blog.activelylazy.co.uk\\\/\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/activelylazy\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/David-Green\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Code coverage with unit &amp; integration tests - Java Code Geeks","description":"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html","og_locale":"en_US","og_type":"article","og_title":"Code coverage with unit &amp; integration tests - Java Code Geeks","og_description":"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated","og_url":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-10-25T20:43:00+00:00","article_modified_time":"2012-10-21T20:24:19+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg","type":"image\/jpeg"}],"author":"David Green","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/activelylazy","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"David Green","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html"},"author":{"name":"David Green","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/4c77ca256cd47f1e3a9dbe6bd23c3ee7"},"headline":"Code coverage with unit &amp; integration tests","datePublished":"2011-10-25T20:43:00+00:00","dateModified":"2012-10-21T20:24:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html"},"wordCount":1340,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg","keywords":["EMMA","JUnit","Selenium"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html","url":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html","name":"Code coverage with unit &amp; integration tests - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg","datePublished":"2011-10-25T20:43:00+00:00","dateModified":"2012-10-21T20:24:19+00:00","description":"On a pet project recently I set out to build automated UI (integration) tests as well as the normal unit tests. I wanted to get all of this integrated","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/selenium-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/code-coverage-with-unit-integration.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Code coverage with unit &amp; integration tests"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/4c77ca256cd47f1e3a9dbe6bd23c3ee7","name":"David Green","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cf9ddd0e6abcf047fa13c218e71f31e80e0fb1e9ff0e7c6b95499bb6727fc8e1?s=96&d=mm&r=g","caption":"David Green"},"description":"David Green is a developer and aspiring software craftsman. He has been programming for 20 years but only getting paid to do it for the last 10; in that time he has worked for a variety of companies from small start-ups to global enterprises.","sameAs":["http:\/\/blog.activelylazy.co.uk\/","https:\/\/x.com\/http:\/\/twitter.com\/activelylazy"],"url":"https:\/\/www.javacodegeeks.com\/author\/David-Green"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/97"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=604"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/604\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/231"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}