This course has been updated! We now recommend you take the Webpack 4 Fundamentals course.

Check out a free preview of the full Webpack 2 Deep Dive course:
The "Coverage Basics" Lesson is part of the full, Webpack 2 Deep Dive course featured in this preview video. Here's what you'd learn in this lesson:

Code coverage is the technique of verifying that code in the application has been “covered” by a test. Kent explains how code coverage is implemented and the background behind the tooling. He also talks about the challenges tools like Babel introduce when using instrumenting code coverage techniques.

Get Unlimited Access Now

Transcript from the "Coverage Basics" Lesson

>> [MUSIC]

>> Kent C Dodds: We left off talking about adding testing to our project. And now we can write tests, in our controller tests we're requiring that controller. We can expect that the controller exists, which is a good thing. Like I said we're not gonna get too far into writing tests, that would be a totally different subject, but I think you can take it from here.

[00:00:28] But there's one other thing that I found in my time with webpack that can be extremely difficult to do and that is setting up code coverage. So does anybody wanna take a whack at explaining what code coverage is?
>> Kent C Dodds: Nobody wants to, can anybody explain what code coverage is, what it does, or even why it's useful, you don't have to explain how it works.

>> Student: It's like a way to check the lines of code that have been touched by a test.
>> Kent C Dodds: Yeah, yeah, so if you think about it conceptually when I'm going through my like my app. When I load up the app, the browser is going to run this code it's gonna say okay I'm gonna create a new controller, it's gonna run this line, this line, this line, it'll run this line and then when this new to do view action is called or that handler is called then this.

[00:01:24] This line will run and so on and so forth, and so let's say that you had something in your code like right now because this is not ES6 code we're saying var that = this, right. So the actual code here is not totally relevant, but if I said and invoke that, I'm gonna have a problem there because foo is not defined.

[00:01:47] Luckily ESLint is gonna let me know that, but if I were running this in a browser or if I didn't run ESLint, then I would never know that that's gonna blow up my program until I ship it off to production. And so that's the value of code coverage is it can tell you whether or not that code is gonna blow up when it's run.

[00:02:08] Potentially, code coverage will not tell you there are two different things. There's code coverage and data coverage, and data coverage is arguably better because it's, and I don't even know if it's a thing to be perfectly honest I'm just making it up, but it would be better because it would tell you, okay this code has run this many times with this type of data.

[00:02:27] So this is run with integers greater than zero and integers less than zero. That would be even better because then you could get a better idea of how your program responds to different kinds of inputs. But the best we have right now is whether or not lines, or run, or if statements were like fallen into or the alternates were executed.

[00:02:49] And so that's what we're going to, that's the problem we're going to be solving next is setting up the tooling for code coverage. But I'm gonna go ahead and let people ask questions if you have any about the value of code coverage. Or how it works. Okay. So let me really briefly, and if you're online and you have questions feel free to ask and interrupt.

[00:03:15] Just really briefly I'm gonna explain kind of how the tooling for code coverage in JavaScript works so. As far as I know there will be a global variable created somewhere in our test that's called coverage, and it's an object. And then that object has properties for every single line, and branch and function in your program.

[00:03:45] And normally it'll be, I can't remember exactly what the key is, but it's some crazy hash and the value would be how many times that line of code was run. And so like in this case you'd say okay, if we wanted to check that, this line, the line above.

[00:04:03] Well, so if this line was run that means that this line was run and this line was run, right. Hopefully that makes sense. So then it would say okay we're gonna take this and say ++. So that means okay, this line has run and then we'll take some other one, and then say ++ and it goes through and adds this stuff to your code everywhere inside of this function.

[00:04:27] If you had an if statement then it'll run it inside, have it inside the if statement. If you, whoops, have a ternary operator like const v = foo, foo otherwise bar whatever, then it would say okay we'll add this and we'll do fancy JavaScript to make it so that foo is what's resolved to there and bar, and of course each one of these would be something totally separate.

[00:04:56] And so that's how this is what's called instrumenting your code. For code coverage and setting up the tooling. There's a bunch of tooling to enable you to do that. But the challenge comes in the fact that we're using several other tools in tandem with these other things. So one of the tools that makes this challenging is Babel.

[00:05:20] So Babel is going to take our code and transpile it. And what that results in often is some code that we didn't write. So let's look at an example of some Babel output here. Just what I have been here, so this is react code. This is a lot of code that we didn't write.

[00:05:39] And so if we said okay, take the output of my Babel code and instrument that. Then we're going to get instrumentation reports on generated code which will inflate or deflate our code coverage results. The end result being inaccuracy and something that changes even when our dependencies change and if Babel changes the way that they do things, and so you want to instrument your source code for coverage, not your transpiled code.

[00:06:06] And because of that it makes things a little bit more complicated. Because you just have to be able to somehow hook into pre-transpilation stuff. But nobody wants to write code coverage stuff all over their code. That would be a bad idea for a lot of reasons, not the least of which performance.

[00:06:23] So all of that to give kind of a framework for why we even care about instrumenting our code for coverage.