Transcript from the "Unit Testing with Jest" Lesson
>> So we're gonna be doing unit testing because, yeah, that makes the most sense for what we're doing. So we're gonna use a framework called Jest to do some unit testing. And we're not gonna write tests on everything. We're not gonna get 100% test coverage right now, but we'll write enough tests to understand how it works, and how to use it, and things like that.
[00:00:20] So Jest is a testing framework created by Facebook that's heavily based off of other testing frameworks that came before it like Mocha and Jasmine. Jest is just like, it learned from all those people. Yeah, it learned from all of those and incorporated things that worked, didn't incorporate things that didn't work, and it's kind of just been adopted as a standard going forward for most of the tests.
[00:00:46] You can even test the front-end stuff with Jest, it's very generic. So yeah, let's do that. First thing we'll do is we'll make a new directory on our root called tests, plural. I'm gonna get rid of this test.js file that I have, not to be confused. So then inside of there, we're just going to test the notes.
[00:01:04] So we're gonna say, notes.test.js. So there's somewhat of a convention here, but it doesn't really matter, cuz you can tell Jest to test any file that you want. But if you have .test in your file name, it will automatically look for that file and test it. How do you think Jest finds the files in your app?
[00:01:27] What do you think it uses?
>> Yeah, but what module?
>> The fs.
>> The fs module, yeah, Jest uses the fs module to find files in your app. It looks to see if any of them has .tests and then it imports them. So, like I said, fs module's strong.
[00:01:46] It does a lot of automations and stuff, so that's what Jest is doing. Let's look at the anatomy of a test. So, It's pretty simple. At the end of the day, your test is gonna be executed in a sub environment. It's still Node.js, but it's being wrapped by Jest, which is providing its own global tools for you, basically.
[00:02:11] So one of the tools is a function called test. So with this function called test, we're gonna do things. So we can say, test, we can describe the test that we wanna do. I wanna test('add takes two numbers and return a sum'), right? We would do that. That takes a call back.
[00:02:34] And I'm just gonna make a function called add here, takes a number, And another number, and just returns the sum of them. So all I'm going to do is run that code and I'll get the result. I'll say result = add(1,2), so that should get back 3. And then what I can do is I can use the assertion library that's built into Jest, which is called Expect, and I can do different assertions on it.
[00:03:13] I can basically check to see if something is what it's supposed to be or not. So in this case, I can say, I expect(result).toBe(3). I expect result to be 3. I think there's a .toBe. Let's look it up. Let's see. Jest, Matchers. Let's see, .toBe, there is, there we go.
[00:03:46] So, yeah, you could do expect something to be some other things. So let's try that. So now, to run the test, I'm gonna go to package.json. If you look at the scripts object, there's already something here called test. If you run it, you'll just get back an error.
[00:04:01] So to run anything in the scripts section of the package.json, you can just do npm run, and then the name of the script. In this case, test. So if you do npm run test, you'll run a test. In this case, you'll see that it says it's missing the script test, and that's because test is a special one.
[00:04:25] I don't know why they made some special and some not special. Test, you don't actually have to type run, you can just type npm test, like you have to, and that will actually run the test. But you can see we don't have any test specified, so it throws an error.
[00:04:44] That's the error we're getting. But you can add any script you want here. You can put, I don't know, thing and you can write any bash stuff in here. It'll run it, whatever you want. Anything that'll work in the terminal, you can do there. So we're gonna replace this with Jest.
[00:05:01] And then we need to install it, right? So npm install jest. Once you use the --save-dev flag to save a module, it's going to create a new object here in your package.json that says devDependencies, which is different than dependencies. The only differences here is a devDependency is a dependency that you don't need to run your app.
[00:05:29] I don't need to test for my app to work. Running the test is a different execution than running the app. It's a dependency that I depend on for developing. So it's a devDependency. And the reason I want to distinguish the two is cuz when I go to deploy in production, I probably don't wanna spend time downloading my devDependencies, because production probably won't need them cuz it only needs to code that it needs for it to run.
[00:05:57] That also depends on your pipeline. Maybe the same system that runs your code in production also test your code. So maybe you do need to install devDependencies. It just really depends. But for the most part, it's clean just to separate them out. Also, for the purpose of this is a package that I'm publishing on npm, other people are going to install it.
[00:06:17] They're never going to test my code. I test my code. So when they type in npm install and install my package, I don't want them to have to also install my devDependencies that they'll never use. So I'm just going to include them in devDependencies. Once they install my package through npm, npm will only install the dependencies that my package depend on, and not the devDependencies that my package depend on, because they're not necessary for my package to run.
[00:06:43] They're only necessary for me to develop with. That makes sense? So this is just for development. This is for actually running. We don't need Jest to run this code. We only need Jest to test this code. Okay, so replace that with Jest, got our test here. And we can just type npm test, and there you go.
[00:07:09] It went and found this test at notes.test.js. You can see right here we have pass, we got a green checkmark, add takes two numbers and returns a sum, and one pass, one ran, everything's good to go. So let's see what happens if we fail this. So like I say, Iexpect that to be 7, then it's gonna say, okay, that one failed.
[00:07:35] So we expected 3, or I'm sorry, we expected 7, and that's what you said you expected to get. But instead, what we received was 3. So something's off here. Either you wrote a bad test or your function's wrong. So in this case, I clearly wrote a bad test, my function's doing the right job.
[00:07:53] So I would change that to 3. And the other alternative way is if I change that. So now, I'm sorry, if I did like this. So now my code is wrong, but I'm expecting it to be a sum, right? So we'll still get to fail, but now it's the inverse.
[00:08:10] So expected the 3, received the -1. So this is why test is good, cuz you can write tests if you know what you need to do, and then you can just go in and make all the tests pass. You heard people say TDD or red green refactor. So go write a whole bunch of tests, because you probably, eventually you'll get to the point where you know what things are supposed to do even before you write the code for them.
[00:08:35] And that's enough to write tests for something you haven't made yet. And obviously, if you run the test for something you haven't made yet, it's gonna break. But if wrote a really good test, all you got to go do is go in and just make all those tests pass.
[00:08:45] And if you made all the tests pass, congratulations, you just wrote the code for the thing. So do people actually do that? I've never met anyone in my life who does that. But I know some companies that are very crazy about doing that. But in reality, it almost never works out that way, in my opinion, at least never with me.
[00:09:06] Sometimes even if I know what I need to do, I definitely don't wanna write tests for it. I'm like, I already know what I need to do, so I don't feel the need to write tests for it, cuz I already know what I need to do. But I can see the argument where like, well, if you know what you need to do, why don't you just write the test for it and then go make those [SOUND]?
[00:09:21] I don't care about that. But on a big team, it's very useful. It's almost necessary. You'll see teams say, we're shooting for 80% test coverage or we're shooting for some threshold of test coverage. There's tools that will analyze the test you wrote, the code that your test tested, and see how much of it was tested, and it'll give you a percentage.
[00:09:41] And if that percentage isn't over a certain threshold, all your tests fail. So some companies will do that where it's like, not only do all your tests has to pass, it has to pass a certain code coverage is what they call it. Yeah, and then it'll even tell you where you didn't test it.
[00:09:56] It'll give you a printout of the code and be like, everything in yellow or red is where you did not test. Still you gotta go right test just for that, if that you forgot to test for, or that else if that you forgot. It's s usually some branch, if else, or something like that, so it gets crazy.
[00:10:13] People in their testing is like a religion. So have fun with that on your jobs, but just letting you know now. And it's probably the hardest thing to setup. So hopefully, it's already set up for you all at your jobs, but coming in new, trying to set up testing infrastructure on a big project is incredibly difficult.
[00:10:32] So I highly recommend taking those courses because it can be tough. There's a million tools that do the same thing. So I'm glad that Frontend Masters has those courses. I might even look at them, to be honest. So obviously, I've been burned by testing, if you can't tell, so.