Writing unit test cases is not enough, for maintaining the quality of the application.
How will we make sure that each scenario has been covered ? Every branches and conditions have been covered in the unit testing ? What if new features or functionality have been added, are they covered in unit test cases ?
Code/Test coverage is the answer to all the questions.
It not only helps in maintaining the quality of the application, but also helps developer in getting deeper understanding of the code. Most of the times, we skip certain conditions and scenario’s assuming that our code will execute properly as intended, but it may happen that, based on the certain inputs it can behave differently.
What can we do, to avoid these conditions and make sure that our code is thoroughly tested. There are certain code coverage tools, that we can integrate with test script.
So, when test cases will execute, they will record the execution of our code files and will check, what code/function/blocks have not been executed during unit testing and will generate the coverage report.
We can also set the threshold/limits for the code coverage tool, that how much percentage of functions/lines/statements needs to be covered while unit test case has been executed, and below that limits we will fail the build.
Lets start by adding coverage to our library, we will be using “Istanbul”.
We will add it as a dev dependency to our library:
npm install -D istanbul
After adding this, we will add/modify the test script in package.json, to add coverage.
"test" : "istanbul cover -x '*.test.js' node_modules/mocha/bin/_mocha -- -R spec src/api.test.js"
In the above test script, we have added a “istanbul cover -x ‘*.test.js’”, which specifies that to record code coverage on all files, except the files with the test.js extensions. After that we have provided the path to the mocha executable and specified that the reporter is “spec” which is the most commonly used reporter.
Mocha available reporters.
Till now we have added the code coverage recording to our library/project.
Lets run the test script: npm run test
We will get the output similar to the below one, which will show the coverage report:
Also, a new directory has been created, with the name coverage, and it will contain the icov report and the coverage.json file.
The Percentage can vary based on the test cases return, in my example I have covered all the scenarios under unit testing.
Note : Do add the coverage directory to the .gitignore file to avoid committing it to the source control.
Viewing the Coverage Report In Browser:
The generated coverage report can be viewed in the browser, navigate to the Icov-report directory under the coverage directory, Open the index.html file in the browser.
In the left panel of the report, it will show the no of times the function or statement has been executed. Also, it will show a red cross, before the function/statement that has not been executed.
Setting the threshold/limit for the code coverage:
The above output shows us the standard coverage report, But how can we validate that, whenever a new feature added or existing functionality modified, the unit testing must be done for them, to avoid any breaking of existing functionality.
We can set the threshold/limits for our coverage reporting and before pushing it to source control, we can validate whether the set threshold have been met or not, if not met we can restrict the code to be pushed into the source control.
Istanbul has an inbuilt module called check-coverage, which we can use for setting the limits for the different specs.
Let’s add another command in the script part of package.json
"check-coverage":"istanbul check-coverage --statements -100 --branches - 100 --functions 100 --lines 100",
"test":"istanbul cover -x '*.test.js' node_modules/mocha/bin/_mocha -- -R spec src/api.test.js"
We have added a check-coverage command in the existing script part of package.json and have specified some limits percentage, that we expect. We can set the threshold limits as required.
Lets run the command, to test whether our coverage report is matching the threshold criteria.
npm run check-coverage
if everything works fine then the output will be similar to the above one.
Now, lets try by adding some dummy function in our code and re-generate the code coverage report.
console.log(“not in use”);
1. Re-generate coverage report: npm run test
We can see that, the percentage have been dropped from 100%.
2. Check coverage: npm run coverage
We can see the coverage validations failed as it didn’t meet the set threshold, that simply states that the newly added code has not been covered in unit testing. We can add the test case for the dummy function, and re run the coverage.
Now, we can add it to the git hooks to avoid committing the code, until the threshold has been met.
Adding Git Hooks:
We will use the ghooks npm module for adding the git hooks to our library.We will install it as a dev dependency.
npm install -D ghooks
Add the config script in the package.json file, and under config add a “ghooks” node, with the
"pre-commit" sub node:
"pre-commit": "npm run test && npm run check-coverage"
Once, it is done and now whenever we try to commit the code, it will initially run the test script, which in turn generates the coverage report and secondly it will check, whether our coverage thresholds has been met or not.
In this way, we can assure that, whatever code has been pushed is unit tested.
In the next article, we will integrate the code coverage reporting service codecov.io , which will take reporting to the next level.
Note: Do add the coverage directory to the gitignore file to avoid committing it to the source control.
Link to my GitHub Repository