Transcript from the "Exercise: Code Coverage" Lesson
>> Kent C Dodds: I've spent a lot of time working on getting this stuff working, and now we finally have a really, really great solution. Which I'm going to show you and then let you wrestle with it a little bit. So the first important part is this plugin with babel. So one of my favorite parts about babel is the fact that it's pluggable.
[00:00:25] And I'm pretty sure a typescript to it also is pluggable, I think. And so that was one of the last things about typescript for me that I wanted was, I needed it to be pluggable. But what this babel plugin does, actually I should stop and just ask, how many people are familiar and use babel?
[00:00:42] Okay, so it's transpiling our es6 with these other presets and stuff, all the presets are doing are loading in plugins for us. And so this es2015 preset has a big list of plugins that consists of all of the various features of es6, or es2015. And so then those plugins will say okay, I found this part of the code that is a class.
[00:01:10] I'm going to transpile it down to prototypes and whatever needs to happen to make that work in es20 or es5, so various things like that. And so, you're not limited to just ECMA script features though, you can do anything with the code. That was a big change with babel 6 that everybody was both excited about and hated, was that now babel is just this platform of pluggable awesomeness.
[00:01:39] But it enabled stuff like coverage. So what this babel plugin does is it just adds those coverage lines all over the code. And it adds it to the variable that just so happens to be cut like a pseudo standard for coverage. So the karma-coverage plugin can take that variable, when all the tests have been run, it says okay, give me that variable, and I'm gonna use that to generate the report.
[00:02:04] I'm seeing some head nods. Does anybody have questions about what's going on? Okay, sweet, so it's basically doing just what I was doing with that underscore underscore coverage mess, but it's doing it in a generated fashion, so we don't have to do it ourselves, which is great. And that's actually the more common tool for code coverage, before, it was a tool called Istanbul.
[00:02:27] And it didn't work with es6, and so they were like Esparta was really popular for a long time. And then that is no longer maintained, and now underscore underscore coverage is great. If you're doing stuff in Node, you should look into a package called NYC. It is now kind of been merged with Istanbul, and it supports es6 with a babel plugin, a different one, and it's great.
[00:02:52] And if you wanna learn more about that, I'm gonna talk about it tomorrow at my open source workshop, so fun stuff. Okay, great, then once you have these things installed, they both need to be configured. And configuration is the name of the game with all this stuff. It's our favorite part of everything, right?
[00:03:07] So the first thing in our babelrc, we're doing this fancy thing right here. The most important piece of this here, actually I'm gonna go into our babelrc in here, so I have a little bit more freedom. So if we wanted to add a plugin to this babelrc, we would add a plugins array.
[00:03:30] And in here, it's just an array of the names of the plugins, so coverage would be the name of that babel plugin that we have in our package json. So it's babel-plugin-name. And so the problem that we have with this specific scenario is, now we're instrumenting our code for coverage, even when we ship it to production.
[00:03:55] Not a really good idea, your app performance will be terrible. It should still work, everything will still work, but it will be very slow. So what we're going to do instead is we only want this particular plugin to be available in some type of environment, that environment is test.
[00:04:17] And so babel has this ability to specify a certain configuration when only something like specific environment requirements are met. And you do that in the env property or object. And as a property of that, it's the value of the environment. So, in our case, we're gonna just call it test arbitrarily.
[00:04:41] And that's where we put the configuration for that test. And I'll show you here in a second how to set up the environment to be equal to test. But that's the important part, or the important piece of this, is that the environment, or you only want this plugin set in a particular environment, and we're gonna arbitrarily call that an environment test.
[00:05:03] Do I have any questions about that? Okay, anything from online or? Okay, so let's go ahead, and we'll set up our environment to be test. And then we'll run our tests, and we should see coverage from that. So if you want to follow along, this would be a good place to start.
[00:05:30] And if you want to just watch and consume, then that's great too. I will give you an opportunity to actually start implementing this stuff once we get some code coverage going here. So the other thing that we're gonna need, well, let's see, I'll just show you how to set up the environment and then you all can do the rest of this stuff.
[00:05:53] So there are two ways that you can trigger babel to have a specific environment. Or to utilize a specific environment, and that is through the environment variable, NODE_ENV or BABEL_ENV. So you set that just as an environment variable, and if you're familiar on the command line, we could say, NODE_ENV=test.
[00:06:20] This is Unix only, if you're on Windows, then you have to kind of do things a little bit differently. But then we could say webpack, and that would run our webpack config with the node environment as test and then babel would instrument our code. Of course, we don't wanna do that.
[00:07:01] But we'll just say the BABEL_ENV is test. And that corresponds to this env right there. So by doing that, then when babel kicks in to transpile our code, it's gonna say okay, here are all the presets, let me go load all of their plugins. The environment is test, so I'm gonna take this test object and merge it with the default plugins as well.
[00:07:26] I'm seeing some nods. Any questions about that? Okay, so the rest of this stuff is a little bit on the boiler platey side, so I will show you how to cheat. But what I want is for you to actually run this yourself and see the output yourself, so you can go to, on my slides, kcd.im/webpack-workshop, so if you're not on my slides, that's where it is.
[00:07:54] And then go to the coverage exercise slide, here actually, well yeah. I can copy this into the chat actually, just really quick. So yeah, go to those slides. And then click on this link to get the diff. And you can even just pop this up in view and copy that.
[00:08:13] And I want you to actually run this and get the coverage yourself though. Yeah, or you can just look at it and type it out yourself. And while you're doing that, I'll explain what the purpose of this stuff is. So first of all, we have these reporters, so karma has this concept of reporters, where in the terminal, if you specify the progress reporter, it's gonna show you, we only have 1 test, so what happens likely going to split.
[00:08:48] But if you have 600 tests, you'll see in the terminal these tests running, and that's the progress reporter. We also want to get code coverage in our terminal, so when our tests are all done, it will spit out what the code coverage looks like. And we want it in general es files as well.
[00:09:04] And so that's where we specify the coverage reporter. And that coverage reporter actually corresponds to this karma-coverage plugin that we're using. And then we configure that this way. So the coverage plugin knows to look in the karma configuration for the coverage reporter to get its config. And here, it has a reporter's array that has a bunch of boiler platey stuff that just says the different types of reporter sites you want.
[00:09:37] There are several different ways to configure this, but not super necessary for you to understand or as far as webpack is concerned to understand that bit. So I'm gonna take us as far as, well, I'm actually gonna check out the next branch, and I'm going to explain to you why this part is important.
[00:10:01] And then we'll go ahead and move on.