Check out a free preview of the full Complete Intro to React, v3 (feat. Redux, Router & Flow) course:
The "Configuring & Running Jest" Lesson is part of the full, Complete Intro to React, v3 (feat. Redux, Router & Flow) course featured in this preview video. Here's what you'd learn in this lesson:

Before running the snapshot test, Brian installs and configures Jest. Part of the configuration includes having Babel transpile the ES6 modules so they can be consumed by Jest. Babel will only transpile these modules when Node is running in a test environment. Brian takes questions from students. - - https://babeljs.io/docs/plugins/transform-es2015-modules-commonjs/ - https://github.com/btholt/complete-intro-to-react/tree/v3-11

Get Unlimited Access Now

Transcript from the "Configuring & Running Jest" Lesson

[00:00:00]
>> 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 web pack 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.

[00:00:18] Right. Or if you have Jest Global installed, you can do that too. So, if I run that, it's automatically gonna find Search.spec.jsx, and then it's going to fail because it doesn't know import. That's right. 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've kind of talked about that a little bit yesterday. That node does not yet understand imports and text. And also even if it did, it would get here and it would throw up because it doesn't understand jsx. Now what we're gonna have to do; is we're gonna have to go our babel rc.

[00:01:08] So, we are back here. We're gonna have to add another top level thing that's gonna say, hey, when in the testing environment you need to also transform modules. So you're gonna put an env up here, which by the way is different from than this env, okay? This is the babel preset env and this is environmental..

[00:01:35] Doing different transformations based on environmental variables. That's what this env refers to.
>> Brian Holt: Okay, and we're 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".

[00:02:14]
>> Brian Holt: And that gives, anyway It's actually, technically, this would work. You can also do babel-plugin, if you wanna be totally verbose, like up here we did transform-class-properties. If you omit the babel-plugin part, so if you just did that, babel inserted for you, it's up to you. My notes will have both versions of it, so either way.

[00:02:40] You don't have to be consistent. So we need to go add this "transform-es2015-modules-commonjs" for the test environment, right. The reason we have to do this is that when you're in the node environment, you have to transform es2015 modules to common js or node's not gonna understand it, right.

[00:03:03] So we're saying when node env equals test, we're gonna run this plugin right here. Keep in mind it's also going to run everything up here. All of these ones up at the top, it's always going to run 100% of the time, and that's also going to run this one.

[00:03:17] Oops. It's also going to run this one, this babel plugin-transform- es201- modules-commonjs. It's also going to run this one only in the test environment, okay? So, save that, and now we're going to go back to our command line. And going to 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.

[00:03:56] I can show you for fish. I don't know how to do it for ZSH or any of the other ones. So, anyway, node or not, we're gonna do .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.

[00:04:22] Okay? Now it's able to understand what's going on.
>> Brian Holt: So let's talk about snapshots and what we actually tested there, right? Cuz what we did was pretty terse. So if we come back to our spec.jsx, spec.jsx, the search one, what we did is we brought in search. So, this search component right here, right?

[00:04:48] 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. And then Jest has this fantastic ability to do what's called snapshot testing. The first time you run Jest snapshot testing, it's just going to accept the first time that you have run it is the correct version.

[00:05:15] Then, in the future, it's going to test to see if that's changed, right? So, if you actually look inside of your test directory now. There's actually an underscore underscore snapshots. Take a look there and open it. You can see that there's a search.spec.jsx.snap and what you can see here is you can see what it's actually rendering out.

[00:05:39] You can see it has a div up here, a header, an H1, input. All of this stuff up here, which is really cool, right? Now if I go 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.

[00:06:09] And I come back here and run this again, it's gonna fail my test because something changed. Right. 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.

[00:06:31] The cool thing about this is it's actually quite easy to update. So once I see it's like no I actually do want it 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, its gonna pass, right?

[00:06:49] Because now I've accepted that as the truth. So again, if you go back to our snap, now it says something else in here.
>> Audience 1: I know a couple of us are still getting an unexpected token import after that update.
>> Brian Holt: Sure.
>> Audience 1: I'm sure other people are as well.

[00:07:07]
>> Brian Holt: So, let's go look at our babel rc again. 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.
>> Brian Holt: If you don't have that you're gonna have a bad time.
>> Audience 1: It's just a typo for me, thank you.

[00:07:32]
>> Brian Holt: Okay [LAUGH]
>> Audience 1: Okay.
>> Brian Holt: [LAUGH]
>> Audience 2: How do you create the snapshot again?
>> Brian Holt: [COUGH] So-
>> Audience 2: That's a command thing?
>> Brian Holt: When you create it for the first time you just have to run Jest, it will just create it automatically, if it doesn't have one for that particular snapshot.

[00:07:46]
>> Audience 2: Okay interesting, and yeah cuz mine just runs, but it shows the test passing but no snapshots. Is that creating any?
>> Brian Holt: So you need to have it inside of your spec, right? So it's looking for this call right here, the tomatchSnapshot. So that's all it's doing. Like this to snapshot function's just saying like hey I'm going to be providing you some sort of JSON structure, right, that's all it is.

[00:08:12] And then it's gonna just do that snapshot sort of testing for you.
>> Audience 2: Yep, I was just missing the parenthesis.
>> Brian Holt: There you go.
>> Audience 2: [LAUGH]
>> Brian Holt: What's cool about this is, this is not just for React. So obviously, this is very well fitted for React, right. But you could totally do this with API responses, right.

[00:08:30] If you have like, if you're testing in API, and you're expecting to return a certain JSON structure, you can use snapshot testing for that as well. Be assured that you're, like the structure of your JSON for your API is not changing over time unless you anticipate it to do that.

[00:08:48]
>> Audience 2: So could you kind of do a test driven design where you'd actually layout your snapshot ahead of time and then say, okay I expect my component to match.
>> 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.

[00:09:07] You were not suppose to edit these by hand. The other thing that people, which may not be intuitive, is you are supposed to check this in the Git. Right? So if you ship this to someone else, they're supposed to get the same snapshot as you. A lot of times people feel kind of icky about checking in things that are machine generated.

[00:09:27] But in this particular case you wanna check these in, just cuz they are part of your testing suite.
>> Audience 2: And the __tests that you created, that's a pre-defined path, right? I mean, cuz I didn't see where we defined that anywhere.
>> Brian Holt: No, so JS is a really smart testing suite.

[00:09:50] 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 Airbnbs es.config is forcing us to put it inside of the test directory. So if for me personally I want my test to live as close to the components of the test as possible, right, 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 test that pertain to those things, I want them to live as close as possible.

[00:10:21] Not everyone shares that particular desire right? Sometimes they wanna have their tests totally separate in another directory that's totally aside from their code, and its all your decision to make. But I'm right, that's what I'm getting at. Cool, questions about Snapshot testing? It's pretty magical, right? Pretty magical.

[00:10:44] Yeah.
>> Audience 3: How is Jest invoking babel?
>> Brian Holt: It just does it automatically.
>> Audience 3: Okay.
>> Brian Holt: It does, is the answer to that question [LAUGH].
>> Audience 3: Okay. And I don't see like any transpiled JS files sitting anywhere. So is it just a in-memory pipeline that.
>> Brian Holt: Yeah, I think so, is the answer that question?

[00:11:07] 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 ready into something like top directory something like that. But that's conjection, I'm not actually sure Yeah, Mark?
>> Audience 3: If I change one file and want to update the Snapshot, how do I do that?

[00:11:26]
>> Brian Holt: So if I come back here, so actually I'm gonna change my title to be correct, so I'm gonna go back to svideo here. I'm also gonna get rid of this initial string, so that search term. So I've modified it. If I run it again, right, it's gonna fail cuz I changed my markup, right?

[00:11:44] It's gonna change in several places, right? So like you know, before it was only rendering out Game of Thrones, because I had game as the initial search thing. Now it's rendering out everything.
>> Brian Holt: Okay, so that's why it's failing right now. So the answer to the online question, I just run it again but with -u.

[00:12:06] If I run it again with -u, it's gonna update the snapshots. I'm asserting that what I just output is now the new truth. So now it's back to what it is. And if we go back and look at our snapshot You can see here, it's all of this stuff.

[00:12:35] Other questions?
>> Audience 2: Who made Jest?
>> Brian Holt: Facebook.
>> Audience 2: Is that Facebook? And you said it's jasmine underneath?
>> Brian Holt: Yup, jasmine two.
>> Audience 2: Jasmine two, 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, it's just has a bunch of these convenience features built on top of Jest.

[00:13:01] Another really cool thing is with Jest, if you have a bunch of tests that you're running, like whole speeds, it'll run them in parallel so it'll go faster. It will run the tests that last failed first so that you can hopefully fail faster, rather than having to wait to go through the entire test suite.

[00:13:16] There's just a whole boat load of really useful things that they're doing for you. Yeah, cool indeed I think so.
>> Audience 1: Okay. May be a specific question but, if you only want to update one or two files and not run the whole -u, I imagine the -u is globally updating your tests.

[00:13:36]
>> Brian Holt: It is. I don't know.
>> Audience 1: You don't run into that often though?
>> Brian Holt: Yeah, I haven't run into that often enough. I'm wanna, let's see if we can figure out we show a man just I don't know. I think you can pass a specific file string, I don't know if you can do like per test level or prior to do that per file level, I don't know, that's the answer to your question.

[00:13:58]
>> Audience 1: I must in this case if you wanna do that
>> Brian Holt: So, I'm getting sick of running the super long command. So let's actually just go put that into our package adjacent. So we're gonna put in two commands real quick. The first one, as you might imagine, is test jest.

[00:14:18] Pretty easy.
>> Brian Holt: The only thing that it Jest has is it has a lot of mocking abilities, the kinda stuff that comes with sign on built-in. I don't really know too much about them, cuz they kind of a pain to use and I think mocking, a lot of times, does more harm than good.

[00:14:35] [LAUGH] But it's all there. So, as you remember, even though I don't have Jest globally installed, it can pull string from the node modules. And then I'm gonna create another one. And it's going to be test:update and it's gonna be jest -u.