This course has been updated! We now recommend you take the Complete Intro to React, v7 course.
Transcript from the "Configuring & Running Jest" Lesson
>> Brian Holt: Now we have this test, so how do we run it? Let's go back to your command line really quick. I have webpack running, but you don't have to have it running, I'm just gonna leave it cuz I'm lazy. Okay, and then what we're gonna do, we're gonna say ./node_modules/.bin/jest, right?
[00:00:19] Or if you have Jest globally installed you can do that too. So if I run that, it's automatically going to find search.spec.jsx, and then it's going to fail because it doesn't know import. That's right. And so let's go fix that too. So the problem is, if we go back here, this is trying to be run in Node and Node doesn't know how to do import, right?
[00:00:52] We have kind of talked about that a little bit yesterday that Node does not yet understand import syntax. And also, even if it did, it would get here and it would throw up because it doesn't understand JSX. So, now what we're gonna have to do, we're going to have to go to our babel.rc.
[00:01:11] So we're back here. We're going to have to add another top level thing that's going to say, hey, when in the testing environment you need to also transform modules. You're going to put an env up here, which by the way is different from this env, okay. This is the babel preset env and this is environmental, doing different transformations based on environmental variables.
[00:01:39] That's what this env refers to.
>> Brian Holt: Okay, and we're saying when node env equals test, then, run this plugin, that's what we're gonna do. So plugins.
>> Brian Holt: And all we're gonna do, the only additional plugin that we're gonna run is transform es2015-modules-commonjs.
>> Brian Holt: Yeah I guess, anyway, it's actually, technically this will work and you can also do babel-plugin if you wanna be totally verbose.
[00:02:26] Like up here we did transform class properties. If you omit the babel-plugin part, so if we just did that, that will insert it for you. It's up to you. My notes here have both versions of it, so either way, you don't have to be consistent. So we need to go add this transform-es2015-modules-commonjs for the test environment, right?
[00:02:53] The reason we have to do this is that when you're in the Node environment you have to transform-es2015-modules to commonjs or Node's not gonna understand it right. So we're saying when node env equals test we're gonna run this plugin right here. Keep in mind that's also going to run everything up here.
[00:03:11] All of these ones up at the top, it's always going to run 100% of the time. And it's also going to run this one. Oops, it's also going to run,
>> Brian Holt: This one. This babel-plugin transform-es2015-modules-commonjs. It's also going to run this one only in the test environment, okay?
[00:03:37] So save that. And now we're going to go back to our command line. And we're gonna say, NODE_ENV=test. By the way this works for bash, so if you're in something like fish, you have to do something different. I can show you for fish, I don't know how to do it for zxs or any of the other ones.
[00:03:58] So anyway, we're gonna do ./node_modules/.bin/jest, like that. So again this is for bash but I'm assuming if you're using another shell that you're smart enough to translate that into something else, okay? Now it's able to understand what's going on. So let's talk about snapshots and what we actually tested there, right?
[00:04:33] It's cuz what we did was pretty terse. So if we come back to our spec.jsx, the search one, what we did is we brought in search. So this search component right here, right, the one we wrote yesterday.
>> Brian Holt: We then rendered it out with no additional parameters, we then took that component and we made it to a JSON structure.
[00:05:02] And then just as this fantastic ability to do what's called snapshot testing. The first time you're on jest snapshot testing, it's just going accept the first time that you have run it as the correct version, then in the future, it's going to test to see if that's changed, right?
[00:05:20] So, if you actually look inside of your test directory now, there's actually this __snapshots. Take a look there and open it and you can see that there is a search.spec.jsx.snap, right? And what you can see here is you can see what it's actually rendering out.
>> Brian Holt: So you can it has a div up here, a header, an h1 input, all of this stuff up here.
[00:05:47] Which is really cool, right? Now if I go to back to search.spec.jsx, sorry. What I meant is back to search.jsx. And I change this to be, I don't know, something like, well here in the header. If I change this to be something else in the h1 and I come back here and run this again, it's gonna fail my test because something changed, right?
[00:06:17] It's gonna say, hey, this used to have svideo and now you have something else. Your test now is failing because something's changed. Now you might be telling yourself, well, sometimes my markup changes, right, like I want it to change. The cool thing about this is it's actually quite easy to update.
[00:06:36] So once I've seen it's like no I actually do wanted to say something else, I just run jest again with -u, and now it's going to go rewrite my snapshot. And so now when I run it again it's going to pass right now because now I've accepted that as the truth.
[00:06:51] So again if you go back to your snap, now it says something else in here.
>> Speaker 2: I know a couple of us are getting an unexpected token import after that update, I'm sure other people are as well.
>> Brian Holt: Sure, so let's go look at our babel.rc again.
>> Brian Holt: So you need this env thing right here, right, down at the bottom, so that in the test environment it's running this plugin, transform-es2015-modules-commonjs.
[00:07:26] What's cool about this is this is not just for React. Well, obviously this is very well-fitted for React, right, but you could totally do this with API responses, right? If you're testing an API and you're expecting it to return a certain JSON structure, you can use snapshot testing for that as well to be assured that, the structure of your JSON for your API is not changing over time unless you anticipate it to do that.
>> Speaker 3: So could you kinda do a test driven design where you'd actually lay out your snapshot ahead of time? And then say okay, I expect my component to match that?
>> Brian Holt: I would not do that. Snapshot.spec.jsx, in fact, I think it says it in there. I'm not telling you what you can and can't do, by all means, but you were not supposed to edit these by hand.
[00:08:16] The other thing that people, which may not be intuitive is that you are supposed to check these in the Git, right? So that if you ship this to someone else they're supposed to get the same snapshot as you. A lot of times people feel a kind of icky about checking in things that are machine generated.
[00:08:32] But, in this particular case you want to check these in, because they are part of your testing suite.
>> Speaker 3: And the __tests that you created, that's a predefined path, right? Cuz I didn't see where we defined that anywhere.
>> Brian Holt: No, I think so jest is a really smart testing suite.
[00:08:54] That it's just going to scour your entire code base for things that say .spec, .js, jsx. So we could really put it in that top level directory. But Airbnb's eslint config is forcing us to put it inside of the test directory. For me personally, I want my tests to live as close to the components of the test as possible.
[00:09:16] So that if I go into a directory and I see that test directory and I can just open it and I can see all the tests that pertain to those things. I want them to live as close as possible. Not everyone shares that particular desire, right? Sometimes they wanna have their test totally separate in another directory that's totally aside from their code.
[00:09:33] And it's all your decision to make.
>> Brian Holt: But I'm right, that's what I'm getting at. Cool, any questions about snapshot testing? It's pretty magical, right? Pretty magical, yeah, magical, yeah?
>> Speaker 4: How is jest invoking babel?
>> Brian Holt: It just does it automatically.
>> Speaker 4: Okay.
>> Brian Holt: [LAUGH] It does is the answer to that question.
>> Speaker 4: Okay. And I don't see any transpiled js file sitting anywhere, so is it just a in memory pipeline that?
>> Brian Holt: Yeah, I think so, is the answer to that question. I'm not exactly sure where it's storing that. I mean there is babel cache and things like that, but my guess is it might be writing out to like the temp directory or something like that.
[00:10:22] But that's conjecture, I'm not actually sure.
>> Speaker 5: Who made jest, is that Facebook?
>> Brian Holt: Facebook.
>> Speaker 5: And you said it's Jasmine underneath?
>> Brian Holt: Yep, Jasmine 2.
>> Speaker 5: Jasmine 2, so, what's the difference?
>> Brian Holt: Snapshots are specific to Jest, the smart finding of files is specific to Jest, the automatic running of Babel.
[00:10:43] It just has a bunch of these convenience features built on top of Jest. Another really cool thing is with Jest, if you have a bunch of tests that you're running, like whole suites, it will run them in parallel, so it will go faster. It will run the test that last failed first, so that you can hopefully fail faster, rather than having to wait to go through the entire test suite.
[00:11:04] There's just a whole boatload of really useful things that they're doing for you. Yeah, cool indeed, I think so.
>> Speaker 2: Maybe a specific question, but if you only want to update one or two files and not run the whole -u, I imagine that -u is globally updating your tests?
>> Brian Holt: I don't know.
>> Speaker 2: You don't run into that often though?
>> Brian Holt: Yeah, I haven't run that into often enough. Let's see if we can figure it out, right? Is there a main jest? Anyway, I think you can pass in specific files to run. I don't know if you could do it at per test level, but you probably can do it at a per file level.
[00:11:44] But I don't know if I've answered that question.
>> Speaker 2: I was mostly just curious if you run into that.
>> Brian Holt: Uh-uh.
>> Speaker 2: Cool.
>> Brian Holt: So I'm getting sick of running this super long command. So let's actually just go and put that into our package.json. So we're gonna put in two commands real quick.
[00:12:02] The first one as you might imagine test jest, pretty easy. The other thing that jest has is it has a lot of mocking abilities like kind of stuff that comes with sign on, built in. I don't really know too much about them because they are kind of a pain to use, and I think mocking a lot of times does more harm than good.
[00:12:24] But that's all there. So, as you remember even though I don't have jest globally installed, you can pull it straight from the Node modules. And then I'm gonna create another one, and it's gonna be test:update and that's gonna be jest -u.