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 going to get too far into writing tests, that would be a totally different subject, but I think you can take it from here.
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 want to 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 going to say okay I'm going to create a new controller, it's going to 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.
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 foo.bar and invoke that, I'm going to have a problem there because foo is not defined.
Luckily ESLint is going to 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 going to 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 going to blow up when it's run.
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.
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.
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 going to 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.
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.
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 going to 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.
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.
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.
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.
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.
So all of that to give kind of a framework for why we even care about instrumenting our code for coverage.