Cover your tests
Welcome back, I am going to explain why you should be running most of your tests with some sort of code coverage. Code coverage is a software testing metric that analyzes how effective your tests are when ran with your code. Code coverage enables you to see the degree to which your code has been implemented. It also helps you to determine how successful unit tests are by checking the degree to which your code is covered by them. Code coverage percent is calculated by items tested by dividing elements tested by elements by elements found.
Code coverage enables you to improve the efficacy of your code by having a statistical analysis of code coverage. The test cases your currently running without code coverage may be less effective than you realize. Running with code coverage allows you to identify parts of your software that have not been examined by your test cases. This not only makes better code but it saves time because it gives you a clearer picture of where you need to refactor.
Code coverage enables you to identify parts of the software that are not implemented by a set of test cases.
How is code coverage calculated?
Well, that depends on what tools you’re using. However the common tools combine some of the following types:
- Line coverage: percent of lines tested
- Functions coverage: percent of functions called
- Conditions coverage: percent of boolean expressions covered
- Branch coverage: percent of branches executed
Are all code coverage types created equal?
When I first learned about code coverage, I assumed that line coverage must be superior, because hitting every line must be most important and probably will include most methods. While this is important it will miss out on a few things. Consider the following code from a stackoverflow answer:
public int getNameLength(boolean isCoolUser) {
User user = null;
if (isCoolUser) {
user = new John();
}
return user.getName().length();
}
When you call this method with the boolean variable isCoolUser set to true, you will have your line coverage come back 100%. However, this method has two paths;
- boolean is true
- boolean is false.
If the boolean is true, all lines are executed, and code coverage will return 100%. What we don’t see with line coverage is that if you call this method with the boolean set to false, you will get a null pointer. Line coverage wouldn’t show you this bug, whilst branch coverage would. For these reasons, best practice is to use a coverage tool that examines multiple types of code coverage
You’ve convinced me, so how do I start?
Code coverage comes built into most IDE’s. In intellij, when you open the run drop-down menu, its two buttons below, “Run with Coverage”. I have found this tool incredibly useful/invaluable in my coding. Since learning of it, I have not run tests without using coverage. There have been a few instances where I created test classes that passed but I wasn’t aware just how terrible they could be. Using code coverage has made me learn more and see my mistakes much more easily. Lines I thought were testing the code, I could comment out and see if it reduces code coverage and learn from that. In Intelli-j’s code coverage, lines that have been executed are green while lines that aren’t are red.
Other code coverage tools are listed below:
SonarQube
JaCoCo
Clover
Selenium
Carina
Cucumber
Good coverage can’t fix bad test writing practices.
If your tests aren’t comprehensive, covering multiple possibilities, coverage won’t save you.
Thanks for taking the time to stop by and read my blog.
I learned quite a bit of information from the following links:
https://ardalis.com/which-is-more-important-line-coverage-or-branch-coverage/
https://www.softwaretestinghelp.com/code-coverage-tutorial/#Methodologies
From the blog cs@worcester – Coding_Kitchen by jsimolaris and used with permission of the author. All other rights reserved by the author.