1. 28
    Add Code Coverage to tests in a Webpack project
    6m 30s

Add Code Coverage to tests in a Webpack project

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 3 years ago

How much of your code runs during unit testing is an extremely valuable metric to track. Utilizing code the karma-coverage plugin and babel-plugin-__coverage__ plugin, we can get an accurate measure of how well we’re covering the files that we are testing.

[00:00] To add testing code coverage to our webpack application with Karma, we can install as a dev dependency the karma-coverage plugin. With that installed, we can verify that installed right here.

[00:13] Then, with our Karma configuration, we can add the configuration for this plugin. We'll add it to our reporters as the coverage reporter. Then, we'll add a coverage reporter object here, where we configure this plugin. It accepts a reporters array here. These are the different types of reporters that we want to have for our output.

[00:37] I'll go ahead and add a couple here. Here, we have LCOV report, and JSON report, and a text summary report. The LCOV report will generate a HTML report that we can look at in the browser locally. Then, the text summary is nice because it adds the output in our terminal, so we can look at the output there as well as a summary.

[00:57] We're going to be saving this to the coverage directory. With that, if we go ahead and run our test, we're going to get the text summary report right here in our output. We're also going to get this coverage folder with the LCOV report right here. It has an index.html that we can open up and look at the coverage report.

[01:18] If we simply open the coverage/lcov-report/index.html, then we're going to see that we have 100 percent coverage. Hurray! Just kidding. We have 100 percent of nothing. We need to actually instrument our code for coverage, so that Karma knows what to report.

[01:35] Because our code is being transpiled by Babel, we need to instrument our code for coverage before Babel transpiles it. Otherwise, we're going to be instrumenting transpiled code for coverage, and we'll get incorrect coverage numbers.

[01:49] There's actually a coverage plugin for Babel that we can utilize to instrument our code for coverage before everything else is transpiled. We'll install it with npm install as a dev dependency, babel-plugin__coverage__. With this installed, we can verify this in our package.json right here. We can now add this plugin to our Babel configuration in our .babelrc file.

[02:15] In our scenario, we only want this coverage plugin to be added in a test environment. We don't want to actually ship instrumented code to production. That would be a bad idea.

[02:24] We're going to utilize the ENV property in a .babelrc file. Add ENV object here. In here, our ENV will be test that we're applying these plugins to. The plugin that we're going to be using is the coverage plugin here.

[02:43] Now, to have this plugin be applied in our scenario, we need to set the Babel environment, or the node environment, to test when we start up Karma. We can do this easily in our Karma configuration by saying process.env.Babel_Env = test.

[03:00] Now, if we run our test, we're going to see some coverage. If we look at our coverage in the browser, we'll see we have a JS file, we have our controller. We're not getting very good coverage on this because we're not doing much with that file right now as far as test.

[03:17] We also see the controller.test.js file. We have great coverage on this. It's loading our coverage numbers because we don't care about the coverage of our test. We mostly care about the coverage of our application code.

[03:29] This needs to be excluded from what is being instrumented by the coverage plugin. We can do this fairly easily in the .babelrc file by providing options to this coverage plugin.

[03:39] We do this by turning this plugin into an array. The second item in the array are the options. Here, our option will be Ignore. Here, we'll provide a glob to ignore. That will be .test.. Anything that has .test in the name, we don't want to have instrumented for coverage.

[04:00] Now, if we run the test again, we'll see that our coverage numbers are a little bit different. If we refresh our browser, we'll see that only the controller is being reported as having any coverage recorded.

[04:12] Even though this coverage isn't very good, this is what we want, so that we can cover only our application code. Then, we can start running test for the controller and see this coverage number go up.

[04:21] I've taken the liberty of running actual test for this controller, something that will allow us to create a new instance of the controller. I created a Views tab and Models tab file. I don't want to instrument those for coverage either. I added this to our Ignore, so that we ignore both the test and stub files.

[04:40] Now, we can actually see some more of our code being covered if we run npm t to run this test. We'll see that the text summary for our coverage indicates that our coverage has gone up. If we refresh our browser, we'll see that the controller has some more coverage.

[04:56] We can start iterating on this. We could also run this with the watch mode npm run watch test. This way, we can iterate, and add more tests, and see our coverage go up, and review the coverage report in the browser to find the different places in our code that are not being covered.

[05:14] Let's go ahead and review. What we had to do to get coverage working in our Karma webpack project, we first had to install the karma-coverage reporter. Then, we went in to our Karma config file. We added coverage to the list of reporters.

[05:28] We added a coverage reporter. Then, we added some configuration for the reporters that we wanted to utilize. Then, we installed the coverage plugin for Babel, and added that to our .babelrc file, but only for the test environment.

[05:42] Then, we went to our Karma config and added Babel_ENV = test, so that this plugin would be utilized. Then, we discovered that the controller test file was being included. We added this Ignore option to our coverage plugin. Then, I added a couple extra test-related files and actual test. We added this stub to our ignore glob.

[06:08] One last thing that I'm going to go ahead and add to this is, in our validate script, which is run as a pre-commit hook and is useful when starting up the project, I'm also going to have it run the test.

[06:20] Now, when I go ahead and commit code, it also runs the test to make sure that none of the test break. That's how you add code coverage to your Babel transpiled code with Karma.

Marcos Hernandez
Marcos Hernandez
~ 5 years ago

I can't get the coverage to run the files. I get 100% coverage on 0 files. Using the same webpack config, .babelrc and karma config (the same result using babel-plugin-coverage and babel-plugin-istanbul