{"id":66,"date":"2024-01-09T22:12:31","date_gmt":"2024-01-10T01:12:31","guid":{"rendered":"https:\/\/springmasteryhub.com\/?p=66"},"modified":"2024-01-09T22:12:31","modified_gmt":"2024-01-10T01:12:31","slug":"use-coverage-as-a-guide-not-a-goal","status":"publish","type":"post","link":"https:\/\/springmasteryhub.com\/?p=66","title":{"rendered":"Use Coverage as a guide, not a goal"},"content":{"rendered":"\n\n\n<h2 class=\"wp-block-heading\"><strong>Introduction<\/strong><\/h2>\n\n\n\n<p>If you are a developer, you probably know what code coverage is. It is a metric that tells you how much of your code is executed by your tests. It is often used as a way to measure the quality of your tests and your code.<\/p>\n\n\n\n<p>But is coverage a reliable indicator of quality? Does it guarantee that your tests are effective and that your code is bug-free? The answer is no.<\/p>\n\n\n\n<p>In this article, I will explain&nbsp;why coverage is not enough&nbsp;to ensure the quality of your tests and your code,&nbsp;how coverage can be misleading&nbsp;and give you a false sense of security, and&nbsp;how to use coverage as a guide to identifying what to test.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What some developers think coverage is good for:<\/h2>\n\n\n\n<p>Code coverage is a metric that shows how much of your code is exercised by tests and it\u2019s often used by tools like Sonar as a quality gate.<\/p>\n\n\n\n<p>Maybe you are confident that you can do a refactoring in your code. Because of the high coverage, you think there\u2019s no chance you going to miss a possible bug. Assuming that high coverage means low risk.<\/p>\n\n\n\n<p>However, this is a big mistake!<\/p>\n\n\n\n<p>Code coverage doesn\u2019t guarantee good test quality or good code quality. It is only one aspect of testing, and it should not be used as the sole criterion for evaluating your tests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How coverage can hide problems that show up in production:<\/strong><\/h2>\n\n\n\n<p>Coverage can be misleading. You can make your tests exercise the code without testing anything. This will make you miss some bugs that can cause you trouble at a later time.<\/p>\n\n\n\n<p>When you write tests and the assertions are not meaningful enough, and they are too generic, or even worse you don\u2019t have any assertions. You are just invoking the method that is going to be tested, and not checking the behavior and results. The test coverage will not check the quality of your test suite. It will only measure if you covered all the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Let\u2019s see this example:<\/strong><\/h2>\n\n\n\n<p>So you have this Calculator class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class Calculator {\n\n    \/\/ A method that adds two numbers\n    public int add(int a, int b) {\n        return a + b;\n    }\n\n    \/\/ A method that subtracts two numbers\n    public int subtract(int a, int b) {\n        return a - b;\n    }\n\n    \/\/ A method that multiplies two numbers\n    public int multiply(int a, int b) {\n        return a * b;\n    }\n\n    \/\/ A method that divides two numbers\n    public int divide(int a, int b) {\n        if (b == 0) {\n            throw new ArithmeticException(&quot;Cannot divide by zero&quot;);\n        }\n        return a \/ b;\n    }\n}\n\n<\/pre><\/div>\n\n\n<p>Writing tests to have 100% coverage in this code can be something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\n    public void testCalculator() {\n        Calculator calculator = new Calculator();\n\n        calculator.add(2, 3);\n\n        calculator.subtract(5, 2);\n\n        calculator.multiply(3, 4);\n\n        calculator.divide(10, 2);\n\n        try {\n            calculator.divide(5, 0);\n            fail(&quot;Expected an ArithmeticException to be thrown&quot;);\n        } catch (ArithmeticException e) {\n            \/\/ Do nothing\n        }\n    }\n\n<\/pre><\/div>\n\n\n<p>The result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image.png?w=1024\" alt=\"\" class=\"wp-image-69\" style=\"width:579px;height:auto\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-3.png?w=1024\" alt=\"\" class=\"wp-image-72\" \/><\/figure>\n\n\n\n<p>This simple test gives the calculator class 100% of coverage! However, it&#8217;s not checking anything. It only calls the methods with valid parameters. So the coverage will be high because you are running all the class code. But it won\u2019t detect anything if someone adds a bug in the code. This bug can break the business rules.<\/p>\n\n\n\n<p>If you change de <code>add<\/code> method for something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n  public int add(int a, int b) {\n        return a - b;\n    }\n\n<\/pre><\/div>\n\n\n<p>Your test will not detect any problem, and you still will have 100% line coverage:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-4.png?w=1024\" alt=\"\" class=\"wp-image-73\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-5.png?w=1024\" alt=\"\" class=\"wp-image-74\" \/><\/figure>\n\n\n\n<p>A bug was introduced, and your tests are not catching it!<\/p>\n\n\n\n<p>Another example would be tests that have no meaningful assertions. They are too generic not checking if your code is behaving properly. For example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n    @Test\n    public void testCalculator() {\n        Calculator calculator = new Calculator();\n\n        int sum = calculator.add(2, 3);\n        \/\/ The test asserts that the sum is not null, which is always true for int\n        assertNotNull(sum);\n\n        int difference = calculator.subtract(5, 2);\n        \/\/ The test asserts that the difference is not equal to zero, which is irrelevant\n        assertNotEquals(0, difference);\n\n        int product = calculator.multiply(3, 4);\n        \/\/ The test asserts that the product is positive, which is not always true\n        assertTrue(product &gt; 0);\n\n        int quotient = calculator.divide(10, 2);\n        \/\/ The test asserts that the quotient is less than the dividend, which is not always true\n        assertTrue(quotient &lt; 10);\n\n        try {\n            calculator.divide(5, 0);\n            fail(&quot;Expected an ArithmeticException to be thrown&quot;);\n        } catch (Exception e) {\n            \/\/ Do nothing\n        }\n        \/\/ The test does not assert anything meaningful because the try catch are looking for all exceptions, but it should be looking for ArithmeticException\n    }\n}\n\n<\/pre><\/div>\n\n\n<p>In the example, our assertions are not meaningful enough. It exercises the code, but will not help much when it comes to detecting problems.<\/p>\n\n\n\n<p>If a developer goes into the code and makes the same change as mentioned before in the add method:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n  public int add(int a, int b) {\n        return a - b;\n  }\n\n<\/pre><\/div>\n\n\n<p>The tests still pass, and the coverage still will be 100%!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-6.png?w=1024\" alt=\"\" class=\"wp-image-75\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-7.png?w=1024\" alt=\"\" class=\"wp-image-76\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">H<strong>ow you can use coverage in your favor:<\/strong><\/h2>\n\n\n\n<p>So maybe you\u2019re thinking, if I can&#8217;t trust coverage to ensure my project is well tested, how can I use coverage in my favor?<\/p>\n\n\n\n<p>Coverage is a great tool to see visually which parts of the code (lines, conditions, functions, etc) are being exercised or not. That\u2019s an awesome tool for that because you can see which partitions of your code need some attention when writing your tests! Also, it helps you come up with more test scenarios for your code. Adding more scenarios you will be a step closer to finding bugs before they go to your production code.<\/p>\n\n\n\n<p>Look at this code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class EvenOddChecker {\n\n    public boolean isEven(int number) {\n        if (number % 2 == 0) {\n            return true;\n        }\n        return false;\n    }\n}\n\n<\/pre><\/div>\n\n\n<p>If we decided to test this simple method and only add a test for the even part:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\npublic void testIsEvenTrue() {\n    EvenOddChecker checker = new EvenOddChecker();\n    assertTrue(checker.isEven(4));\n}\n\n<\/pre><\/div>\n\n\n<p>When you run coverage you\u2019ll see that you only tested part of the method, not all lines of the method were exercised:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-8.png?w=1024\" alt=\"\" class=\"wp-image-77\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-9.png?w=1024\" alt=\"\" class=\"wp-image-78\" \/><\/figure>\n\n\n\n<p>Look at line 9. It is colored differently because it was not covered yet. Coverage shows you visually what your test scenarios missed. Therefore, you can add tests and make sure the scenarios cover all branches of your code.<\/p>\n\n\n\n<p>Then we can go and fix it by adding an odd scenario to cover the missing lines:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\npublic void testIsEvenFalse() {\n   EvenOddChecker checker = new EvenOddChecker();\n   assertFalse(checker.isEven(5));\n}\n\n<\/pre><\/div>\n\n\n<p>That will give us 100% coverage:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-10.png?w=1024\" alt=\"\" class=\"wp-image-79\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/springmasteryhub.com\/wp-content\/uploads\/2024\/01\/image-11.png?w=1024\" alt=\"\" class=\"wp-image-80\" \/><\/figure>\n\n\n\n<p>But remember, you still need to add effective tests to make this worth it.<\/p>\n\n\n\n<p>That\u2019s how to use coverage well. It helps you to focus on the parts that need more attention in your test suite. Now you can go there and write tests with meaningful assertions to cover these forgotten branches.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>In this article, you discovered why coverage is not enough to measure the quality of your tests, how to dodge common pitfalls that can trick the coverage metric, and how to write better tests that exercise the code meaningfully.<\/p>\n\n\n\n<p>I hope you found this article useful and enlightening. If you did, please share it with your friends and coworkers who might benefit from it. And if you want to learn more about effective testing, please follow me on my social network accounts. Thank you for reading and happy testing!<\/p>\n\n\n\n<p><a href=\"https:\/\/twitter.com\/WillianFMoya\">Willian Moya (@WillianFMoya) \/ X (twitter.com)<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.linkedin.com\/in\/willianmoya\/\">Willian Ferreira Moya | LinkedIn<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction If you are a developer, you probably know what code coverage is. It is a metric that tells you how much of your code is executed by your tests. It is often used as a way to measure the quality of your tests and your code. But is coverage a reliable indicator of quality? [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":85,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[13,25,27],"class_list":["post-66","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-junit","tag-java","tag-tdd","tag-testing"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts\/66","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=66"}],"version-history":[{"count":0,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts\/66\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/"}],"wp:attachment":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=66"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=66"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=66"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}