JSJ 411: Unit Testing Jest with Daniel Caldas
Daniel Caldas is calling from Singapore. He currently works as a software engineer for Zendesk and has also worked in Portugal and Germany. He has worked primarily on the frontend with Node and JavaScript. He talks about his experience testing JavaScript, how he got started with Jest, and why he likes it. Daniel finds Jest very easy to use and straightforward. He likes that Jest has a single reference page for documentation. He feels that Jest is largely complete out of the box and has only made a small add on to get rid of Boilerplate in some tests.
Special Guests:
Daniel Caldas
Show Notes
Daniel Caldas is calling from Singapore. He currently works as a software engineer for Zendesk and has also worked in Portugal and Germany. He has worked primarily on the frontend with Node and JavaScript. He talks about his experience testing JavaScript, how he got started with Jest, and why he likes it. Daniel finds Jest very easy to use and straightforward. He likes that Jest has a single reference page for documentation. He feels that Jest is largely complete out of the box and has only made a small add on to get rid of Boilerplate in some tests.
Daniel explains what a snapshot, how they work, and why he prefers fixtures over factories. He gives tips on how to set up your tests so that they are easy to follow. He finds it helps to structure your scenarios in the fixture description. He talks about gotchas in Jest. While Jest is largely easy to use, Jest has been around for a while and breaking changes do happen. It’s important to check what version your code base is using. While there are a lot of free sources around Jest online, he advises listeners to stick as close to the official documentation as possible, or to people associated with Jest, and to read recent stuff. As for conventions, Jest has pretty much everything out of the box and the built in conventions make it easy to navigate any project that uses Jest.
Daniel talks about some of the features available in Jest, converting observables into promises, and tricks he has used to make tests easier to put together. He talks about his method for keeping his mocks and stubs straight. He advises listeners to have some organizational rules, such as starting the imports alphabetically, and to always follow those rules. He talks about how he runs tests and what environments he uses. While Jest is normally used for unit testing, Daniel has also used it for end to end tests, and he talks about his experience with an open source project doing both types in Jest. Daniel concludes the show by advising listeners starting with JavaScript and frontend, don’t think too much about the library you’re going to use because you’ll probably end up using Jest. It’s more important to have unit tests and a proper testing framework at the beginning than anything else. He also invites listeners to check out his open source work on Github.
Panelists
- Aimee Knight
- AJ O’Neal
- Charles Max Wood
**To receive your 40% OFF coupon for Manning Publications (good for all our products in all formats) visit us on Facebook - click on "Send A Message"and type "YES"**
Guest
- Danile Caldas
Sponsors
- Sentry | Use the code “devchat” for $100 credit
Links
- Zendesk
- Jest
- React
- Babel
- ESLint
- Async/Await
- Cypress
- React-d3-graph
- Unrevealed tips for unit testing with Jest
Picks
Aimee Knight:
AJ O’Neal:
Charles Max Wood:
Daniel Caldas:
Special Guest: Daniel Caldas.
Transcript
Hey folks, I'm a super busy guy and you probably are too. You probably have a lot going on with kids going back to school, maybe some new projects at work. You've got open source stuff you're doing or a blog or a podcast or who knows what else, right? But you've got stuff going on and if you've got a lot of stuff going on, it's really hard to do the things that you need to do in order to stay healthy. And one of those things, at least for me, is eating healthy. So when I'm in the middle of a project or I just got off a call with a client or something like that, a lot of times I'm running downstairs, seeing what I can find that's easy to make in a minute or two, and then running back upstairs. And so sometimes that turns out to be popcorn or crackers or something little. Or if not that, then something that at least isn't all that healthy for me to eat. Uh, the other issue I have is that I've been eating keto for my diabetes and it really makes a major difference for me as far as my ability to feel good if I'm eating well versus eating stuff that I shouldn't eat. And so I was looking around to try and find something that would work out for me and I found these Factor meals. Now Factor is great because A, they're healthy. They actually had a keto line that I could get for my stuff and that made a major difference for me because all I had to do was pick it up, put it in the microwave for a couple of minutes and it was done. They're fresh and never frozen. They do send it to you in a cold pack. It's awesome. They also have a gourmet plus option that's cooked by chefs and it's got all the good stuff like broccolini, truffle butter, asparagus, so good. And, uh, you know, you can get lunch, you can get dinner. Uh, they have options that are high calorie, low calorie, um, protein plus meals with 30 grams or more of protein. Anyway, they've got all kinds of options. So you can round that out, you can get snacks like apple cinnamon pancakes or butter and cheddar egg bites, potato bacon and egg, breakfast skillet. You know, obviously if I'm eating keto, I don't do all of that stuff. They have smoothies, they have shakes, they have juices. Anyway, they've got all kinds of stuff and it is all healthy and like I said, it's never frozen. So anyway, I ate them, I loved them, tasted great. And like I said, you can get them cooked. It says two minutes on the package. I found that it took it about three minutes for mine to cook, but three minutes is fast and easy and then I can get back to writing code. So if you want to go check out Factor, go check it out at factormeals. Head to factormeals.com slash JSJabber50 and use the code JSJabber50 to get 50% off. That's code JSJabber50 at factormeals.com slash JSJabber50 to get 50% off.
Hey folks, I'm a super busy guy and you probably are too. You probably have a lot going on with kids going back to school, maybe some new projects at work. You've got open source stuff you're doing or a blog or a podcast or who knows what else, right? But you've got stuff going on and if you've got a lot of stuff going on, it's really hard to do the things that you need to do in order to stay healthy. And one of those things, at least for me, is eating healthy. So when I'm in the middle of a project, or I just got off a call with a client or something like that. A lot of times I'm running downstairs, seeing what I can find that's easy to make in a minute or two, and then running back upstairs. And so sometimes that turns out to be popcorn or crackers or something little, or if not that, then something that at least isn't all that healthy for me to eat. Uh, the other issue I have is that I've been eating keto for my diabetes and it really makes a major difference for me as far as my ability to feel good if I'm eating well versus eating stuff that I shouldn't eat. And so, um, I was looking around to try and find something that would work out for me and I found these factor meals. Now factor is great because a, they're healthy. They actually had a keto, uh, line that I could get for my stuff. And that made a major difference for me because all I had to do is pick it up, put it in the microwave for a couple of minutes and it was done. Um, they're fresh and never frozen. They do send it to you in a cold pack, it's awesome. They also have a gourmet plus option that's cooked by chefs and it's got all the good stuff like broccolini, truffle butter, asparagus, so good. And you can get lunch, you can get dinner. They have options that are high calorie, low calorie, protein plus meals with 30 grams or more protein. Anyway, they've got all kinds of options. So you can round that out, you can get snacks like apple cinnamon pancakes or butter and cheddar egg bites, potato bacon and egg, breakfast skillet, you know obviously if I'm eating keto I don't do all of that stuff. They have smoothies, they have shakes, they have juices, anyway they've got all kinds of stuff and it is all healthy and like I said it's never frozen. So anyway I ate them, I loved them, tasted great and like I said you can get them cooked. It says two minutes on the package. I found that it took it about three minutes for mine to cook, but three minutes is fast and easy and then I can get back to writing code. So if you want to go check out Factor, go check it out at factormeals, head to factormeals.com slash JSJabber50 and use the code JSJabber50 to get 50% off. That's code JSJabber50 at factormeals.com slash JSJabber50 to get 50% off.
CHARLES MAX_WOOD: Hey everybody and welcome to another episode of JavaScript Jabber. This week on our panel, we have Amy Knight.
AIMEE_KNIGHT: Hey, hey from Nashville.
CHARLES MAX_WOOD: AJ O'Neill.
AJ_O’NEAL: Yo, yo, yo. Coming at you live from now Lormagan, bro-bo.
CHARLES MAX_WOOD: I know. So confusing. Like I walked outside in a jacket and I was like, I almost don't need this. I'm Charles Maxwood from devchat.tv. I can't help it. I have to say this. My book's out. Yeah. Okay. We have a special guest this week and that's Daniel Caldus.
DANIEL_CALDAS: All right, Kaldas, you got it almost there. We hear Daniel talking from Singapore.
CHARLES MAX_WOOD: Nice.
Hey folks, this is Charles Maxwood and I just launched my book, Max Coder's Guide to Finding Your Dream Developer Job. It's up on Amazon. We self-published it. I would love your support. If you want to go check it out, you can find it there. The Max Coder's Guide to Finding Your Dream Developer Job. Have a good one. Max out.
CHARLES MAX_WOOD: Do you want to just introduce yourself real quick, let people know who you are and what you're famous for and all that stuff?
DANIEL_CALDAS: Sure. So I'm Daniel. I'm a Portuguese born in Andorra, which is a small country between Spain and France. I started off my career in Portugal working for a bearing company, working mainly on front end, a bit of Node.js as well. And then I evolved from there. I moved on to Germany to work for Trivago. Also as a JavaScript engineer, started getting a bit more into unit testing and UI libraries, small complex stuff. Most recently I moved to Singapore where I worked as a software engineer for Zendesk.
CHARLES MAX_WOOD: Oh cool. Are they based out there? I don't pay much attention to that kind of thing.
DANIEL_CALDAS: Not really. They are based in San Francisco, but they have some Asian headquarters here in Singapore.
CHARLES MAX_WOOD: Oh cool. So, yeah, we brought you on to talk a bit about unit testing and Jest. It looks like most of the focus that I'm seeing here is front end. What is your experience with testing JavaScript? DANIEL_CALDAS: Yeah, so it's mostly around frontend testing. So I started off not with Jest, actually. I started with Karma and Jasmine in Angular 1.6. So this is pretty old stuff, right? I started off by testing small components and this business logic that you have in separate files across large projects. Then eventually things move on and you find better tools and you find hopefully things like Jest that comes with everything in one package. Like, I don't know, you don't need to set up coverage. You don't need to worry about searching for assertions on a library called Mocha or going to check another assertions on another library called Synon. So everyone likes centralized in one place, you have one single reference page for documentation. And that's pretty much where I love about Jest. And I started with Jest about two years ago when I started simultaneously learning a bit about React because I wanted to move out from Angular. And my job was not allowing me to go much on exploring UI and JavaScript frameworks and there was this all new cool stuff coming out and I just wanted to try it out. And I actually started with Jest in one of my open source projects called React D3 Graph, which is basically a wrapper component for D3 in React. I started off with very simple stuff, I would say, mostly to test simple logic around simple and mostly pure JavaScript functions. One thing that popped up right away was snapshot testing. And this was for me like a super game changer because I came from a world where I was, at least as I was taught to program or to write tests, where you have these huge assertions which super use large objects that you say like this needs to be equal to these or assert equals that. And then you need to just copy around, either create your own mock functions to create large objects or yeah, just having the object inline in the, in the assertion. And then for me, this snapshot testing was like real game changer. And with that, you start, you know, knowing around, getting a bit familiar. And then I also, I think I stick with just throughout my, so side projects and then also when I moved to Germany, Turkey, Trivago, luckily they also use test, the Jest for unit testing. There I started doing some more complex stuff on let's say testing not only these pure functions and business logic that you have around, but also going into UI components and having this JSTOM integrations where you basically render components and you do assertions on things that happen that you could almost say that they are end to end, but they are scope to components. Most recently, I think like around three, three, four months, I was writing this Bavel plugin, this is where I kind of found out a little bit a different side of Jest and also like inspire me to write this latest article of mine on based unit testing where basically you remove all the dry setup that you have, all the boilerplate-ish code that you have to write a unit test and instead of repeating yourself everywhere in this small library that I wrote, I used a pattern like that you can see probably in refills and famous projects like Babel or Webpack where you have pictures and basically just define your inputs any outputs and the runtime and a few scripts that you write just take this and do the assertions for you. And I wrote this, I remember like this super small JS file just takes JavaScript input files and matches against an expectation of the plugin that I wrote. And I just realized like, well, we just like made it so simple, so simple to write like a few months later when I found out about this native Jest iterator kind of feature, which is it.h or test.h. Basically, you can specify table-like kind of structure where you define the inputs for your test case and then you define a common test body to perform the assertions on those inputs. They are table-based. And that kind of throws away a bit of work that I did around the script to read all the inputs and match them against the expected outputs of my compiler. So I think that just for me today is definitely the muscle standard for unit testing at JavaScript. Not only for front-end, I would say, but even if you do stuff in the back-end, like when you're testing some some key functions, some helper modules that you might have. It might be the simplest thing that you have to like just set up and make it work with everything out of the box. Coverage, reports, and all that stuff included.
CHARLES MAX_WOOD: Nice. There's a lot here to unpack and you've talked quite a bit about what you like about Jest, so I don't know that we'll dive into that necessarily as much. But you mentioned some of the Jest. What kinds of things have you felt like you needed to add to Jest to make it a little bit easier to use?
DANIEL_CALDAS: Like to be honest, I don't, I think that even when you go for, I don't know, debugging, if you use VS code, even there Jest got your back, like I don't really had to tweak much around Jest to make it work. Uh, so no add-ons specifically.
CHARLES MAX_WOOD: Oh, I thought you said that you'd made like an add-on to do snapshots and things like that.
DANIEL_CALDAS: Yeah, it was more like an extension. It's just a small script like that takes chess as base and reads a bunch of inputs for compiler like library. It's just a Babel plugin. Just uses just snapshots to remove all the boilerplate that you need to do like defining your test cases. Like when you write, like describe, this is my test case, hit test case one, and then you start writing your test case and you do an assertion at the end. Just basically getting rid of all their boilerplate and your test case is just like a JSON-like structure that your script will consume. But that was just more of, I would say, not over-engineered but way to get rid of this boilerplate-ish around Jest because I was just repeating myself time after time and I was just wondering if I could do better, but under the hood, Jest is 100% without any add-ons. So yeah, and snapshotting just makes it easier because you don't need to actually do the assertions yourself. You just run the snapshots and you make sure that you put them under version control and then everything runs smoothly, hopefully.
AJ_O’NEAL: So tell me again, what is the snapshot itself?
DANIEL_CALDAS: So the snapshot itself is literally the output of these compilers. So think of Babel and think of a Babel plugin that imagine that it takes out console logs. So you have code as input, you have code as output, and your snapshot is just the output of code by your compiler or by your Babel plugin. And the small script that I wrote just basically reads all these inputs in sequence and just performs like literally a match snapshot so that you don't need to like describe the test cases and invoke the compiler, the Babel plugin at each test case so you don't repeat yourself. So basically the snapshot is just literally called that the, the plugin output.
CHARLES MAX_WOOD: Gotcha. One other thing I'm seeing in here is fixtures. I remember in the past using fixtures and then people tended to want to use factories instead. So I'm curious, you know, as to what your experience has been with fixtures and why you prefer those over, you know, some kind of factory pattern.
DANIEL_CALDAS: Yeah. So the fixture came along exactly at this point in time when I was writing the Babel plugin, given the, so the scenario in like, a bit of research that I did around how compilers are testing these days. They basically have no boilerplate to the test whatsoever. So basically in Babel, if you look at a plugin, you have a folder for the tests and you have the inputs and your test case basically has a little bit of code that goes through all the inputs and just matches them against the outputs of code of the compiler. So that against factories, it's, I guess, a bit more strict because like if you run your test cases, all of the test cases the same way, you cannot tweak much, right? So if you have a factory, maybe you can have something that is more configurable or you can tweak along the way. While if you have like fixtures, well, for me, it was more of a one-to-one mapping than to have like any kind of personalization around the test setup.
CHARLES MAX_WOOD: Yeah, I'm curious mostly because those kinds of decisions tend to, at least in my experience, shape a little bit the way that you put your tests together, because you either call in the fixture or you call upon the factory to give you an object that's going to act the way you want. I'm wondering, how do you set your tests up so that they're easy to follow what's going on? Because I've seen tests that get really, really hairy and I've seen actually collections of tests where it's hard to figure out where the different things are being tested. And so I'm curious how you put that together and how that ties into your decision to use fixtures.
DANIEL_CALDAS: I see. So I wouldn't say that is a good practice, but it's something that I found out along the way that would help me a lot to structure my fixtures and like making other people that are contributing to the project to understand like what's going on and what has been tested and what hasn't been tested it's for you to organize the way you describe pictures. When I say organize ways, like pure linguistics, let's say you have a library that, I don't know, gets users from a database, and you want to test users that are male or users that are female, you would have a prefix on your picture saying that, okay, this is like the branch of my test cases, there are testing users doing tests against users that are male, and the other is a branch that's testing features against users that are female. I mean, this might not be the most perfect example, but the idea is that you try to structure your scenarios in the fixture description. So just try to follow some internal convention or try to set up some kind of rules with your team in order to make clear and make easier later on to find and to reference parts of our functionalities of the codebase. That you say, okay, I want you to check for this functionality. This is the thing that I need to grab on the repo to find whether it has been tested or not.
CHARLES MAX_WOOD: Testing questions.
AIMEE_KNIGHT: I am unfortunately not 100% here. I'm answering a lot of work conversations in Slack right now. Hopefully they'll be wrapped up soon though.
CHARLES MAX_WOOD: I wish you weren't so important. So you get your tests arranged, you start using fixtures. How do you break up your tests? For example, do you have like one file per class or prototype or one file per feature or? For unit tests, how do you do that?
DANIEL_CALDAS: Yeah, usually, for instance, for this fixtures-based setup that we were mentioning, it would be like one file per input on your whatever compiler or thing you are testing. If you rather have like testing a real application with a more traditional kind of setup, then you would have like one file per, I would say, component and then I will try to break it down in ways that you have, then isolate the tests for your different helper modules. And like try to make as much as possible to isolate wherever helper functions or wherever modules that perform like heavy work in like very decoupled from your, from your UI. So that the UI gets easier to test. And then the, the way they're I usually lay down tests, it's like trying to make them descriptive, like building up a scenario and then trying to take as much as possible from that scenario. And like when I say scenario, it's for instance, in Jest, when you have a describe block, like try to set up as much as possible so that you don't need to repeat yourself along the test cases. And then within the different test cases, like also try to be specific in whatever feature or functionality you're trying to test. Then I think also another thing that is important is like the way you express yourself writing, writing the test descriptions is pretty crucial. I would say like, initially I, I think I would not know how exactly to like, to express myself when I was describing my tests. And, um, I think I just start following more senior people in the company, you're like trying to see around the other zoo. And it, it always falls down like in this pattern where you have like, you describe when something happens and then as more specific you go or as more close to the test case you get, you start performing specific assertions, stuff like something should happen at this step. So basically you start very high level and very like describing the surroundings of the task case itself. And then when you get deep, you get very, you try to get very specific around like the thing that you're really asserting on.
CHARLES MAX_WOOD: So are there any gotchas to jest? I mean, you said it's pretty easy to set up and get going with, but I mean, no tool is perfect.
DANIEL_CALDAS: No tool is perfect for sure. But I think one of the gotchas is that definitely for me, it was at some point, try to understand like, like if you jump into a codebase, like especially if it's like an old codebase and you see that it's using Jest, Jest is been around, I don't know for many years now, but it's been around for a few years and things change and breaking changes happen. So just try to check exactly what version your codebase is using because sometimes. Especially when I started off with Jest and I had my personal projects and I had projects that worked, I would try to use features that would not be available at that version. And as things move pretty fast, you just try to bookmark whatever version you are using and try to refer to the correct documentation because It might be that you're just simply referring to something that does not exist in that version. I remember one of the things that's quite annoyed me was, I think, when Jess migrated to major version 24, they dropped the Regenerator runtime. So I remember I had a bunch of projects, I started seeing around Regenerator runtime, not found, just exploding everywhere. And then it's a bit annoying because you need to provide it yourself, either configuring Babel properly and that kind of stuff. So yeah, definitely try to place yourself whenever you need to refer to some documentation and pay attention to versioning. The other thing is that you also will probably find a lot in a bunch of resources around Jest online, which happens pretty much daily with anything, right? I mean, we see what happens with React. I mean, you just search for I know how to use hooks and you get thrown a 1 million Google results for how to use hooks. The way I try to go about this is just try to stick as much as possible close to official documentation or people that are somehow related with the project or library you're using, in this case Jest, or at the same time, try to read recent stuff. Because probably if you're reading an article from one year or a few months ago, it will just not work the way that the author is describing. And it might be just frustrating for you to try to follow something and just not understanding it.
CHARLES MAX_WOOD: Does that stuff change very often?
DANIEL_CALDAS: I would say not that often. But it's more of you working on projects that are using different versions. And these things are documented where you really don't realize it.
AIMEE_KNIGHT: You mentioned a little bit of the architecture of using Jest and where you place the files and stuff like that, which brought to my mind some of the conventions that come along with using Jest, which I thought was helpful as far as where you place your mocks and tasks and directory structures. Basically, if you follow their conventions, then running things automatically just kind of you fall into the pit of success and it just works. Daniel, you would, do you want to like talk about that for a little bit?
DANIEL_CALDAS: Yeah, I mean, definitely that basically aligns with the fact that Jess has like pretty much everything out of the box. And I think the convention and like the structure that Jest gives you for you to set up your projects is one of them. And you mentioned like, yeah, you have the mocks and you have the test folder and like everything is predefined in a way. If you go like through the documentation or you just look at a project and you see how it's structured. You can navigate basically through any code base that uses Jest and you understand immediately like where tests are and what are those tests addressing? Because usually when you have super nested folder structures, at least in the parts that I work with, you'll probably find several tests, folders, and those tests usually come together with the files that they are testing. So it's pretty much, it's very easy for you to scope in a specific part of the code base and just work around and iterate in whatever part there is and just update the tests accordingly because they are like kind of structured in a way that makes it easier, at least in my opinion.
AIMEE_KNIGHT: I really like that. And then like a couple of other things that I like about Jest, I don't know if you want to talk about these things. I mean, before, when I first started writing tasks, like I'd use sign-on and stuff like that, which I really liked, but I like how like Jest to kind of get everything out of the box so you don't have to like pull in other things for mocking. And then something that I just worked on recently this past week is like integrating it with ESLint. So there's like a ESLint JAS plugin that is really good. Like it makes sure that people don't commit like any skips, commented out tasks, stuff like that, which I'm sure like Jasmine and Mocha and stuff, I'm sure that there's tools like that out there, but the one for ESLint just was pretty easy that I set up.
DANIEL_CALDAS: Yeah, that's like one that I use myself and I think as you mentioned that they do have those tools like probably Jasmine and Mocha and etc, but they are just not as well advocated that like the ESLint chess plugin is because it's pretty much standard and recommended whenever. You set up Jest, you have this plugin that will help you not make these huge mistakes like leaving a skip or ignoring tests. It's a huge help.
CHARLES MAX_WOOD: So do you keep up on what's coming next in Jest?
DANIEL_CALDAS: Not really, to be honest. As much as I would like to, I think this past few months or I would say here, I've been Jest are offering to me. I'm not really looking to be like what's coming next. And I mean, it also didn't appear to me like in a way that, hey, Jest is announcing some change or some next huge feature, but I would love to hear from it if that's the case. But really, I don't know at the moment.
CHARLES MAX_WOOD: So do you have any tricks that make Jest or make your tests easier to put together?
DANIEL_CALDAS: So in terms of tricks I'll give out a few. I think lately, especially when I was working with, I was working a lot with Rx and observables and testing them may get like a bit like tricky, even though you're using Jest, but it's just something that you, it's not easy to get around. Like for instance, like if you have I was using a UI framework that is proprietary in Trivago, and it's purely based on Rx, and every DOM element is a stream, and it's kind of like Svelte Reactivity, but just purely based on Rx. You have these old files, you have several files with utility streams that are shared, and then in order to make them do something, you actually need to subscribe to them, so there's a bit of file-a-plate involved. Also, one thing that I actually note down is that you can make observables, you can convert them into promises. So I think a very good tip that I can give is like if you're testing an observable and like you need to assert some output, like just use to promise, you probably find it within our experimentation, like you use to promise and like you assert whatever Async await to just manage this asynchronous flow gracefully, I would say. If you're using Promises, for me, it feels a bit more natural than observables, like especially with Async await in Jest. One thing though is actually I'm not really sure of this one, but it is considered good practice to return Promises in your tests. So like just don't hang. Whenever you resolve a promise, jesrt as this native dot resolves, a kind of primitive that lets you get the data out of the promise in order to assert on it. So just make sure you return the promise. Otherwise, for some reason, your test might get hanging. And this was already the case with me when I was testing stuff with Karma, Karma and Mocha, like just make sure you return your promises so that you don't don't give anything hanging within your test cases. So in this article that I wrote, the unrevealed tips for testing with unit testing with Jest, I got into one very weird trick. I would say weird because I came along with a weird problem that maybe I placed myself into, which was like, I was trying to test a file that was non-existent in the file system. This basically was a library where you as a client need to define a configuration file. For some reason, we are not providing that configuration file in the test itself. It was not a file that was in your test directory. It was something that was generated at runtime. And what I found out in Jest, after a few hours, I would say, researching is that you have this flag, which is called virtual. And it's like a parameter that you can use in Jest.moc to say that basically this file does not exist yet. So it's something like that. It's kind of pretty weird, but I thought it was really, really interesting. And especially to put it out there and just to spread the word like, yeah, you can do this with Jest. And then, yeah, another one that is kind of trick as well is that when we are testing any dependency, and if you don't know where on the other side, like people are doing like named exports or like export default, is that you can define like whenever you perform a Jest.mock, you can say that you can define the default of the export module by using a flag, which is like underscore underscore ES module. If you define this within your Jest.mock, when you create the gist of mock, you can define the default export property from this third-party module or even a module that you have yourself, but for some reason just uses export default, which I'm not a big fan of.
This episode is sponsored by sentry.io. Recently, I came across a great tool for tracking and monitoring problems in my apps. Then I asked them if they wanted to sponsor the show and allow me to share my experience with you. Sentry provides a terrific interface for keeping track of what's going on with my app. It also tracks releases so I can tell if what I deployed makes things better or worse. They give you full stack traces and as much information as possible about the situation when the error occurred to help you track down the errors. Plus, one thing I love, you can customize the context provided by Sentry. So, if you're looking for specific information about the request, you can provide it. It automatically scrubs passwords and secure information, and you can customize the scrubbing as well. Finally, it has a user feedback system built in that you can use to get information from your users. Oh, and I also love that they support open source to the point where they actually open source Sentry. If you want to self-host it, use the code dev chat at sentry.io to get two months free on Sentry small plan that's code dev chat at sentry.io.
CHARLES MAX_WOOD: So when you're saying you're, you can choose what to import, is this mocking or stubbing out that module or
DANIEL_CALDAS: is it exactly like stubbing out that module? You need to use this underscore underscore ES module flag. Uh, in order then to write on top of that default that is exported on the other side.
CHARLES MAX_WOOD: Okay.
DANIEL_CALDAS: And you can stop stuff. In my article, I gave this example of a library called cookies.js. Basically, I was trying to assert on this setter and getter and it gets quite annoying because I just wanted to do a normal desktop mock, but then you find out that, okay, it's an export default. In that specific case, it was like importing from a transpiled like output, which was like a kind of a factory function with a single entry point kind of weird. And yeah, this is my savior day. If you're stuck in like this kind of situation.
CHARLES MAX_WOOD: One question that I have, because a lot of the examples in that article are about mocking and stubbing. It seems like you use mocks and stubs fairly heavily and to a certain degree, I understand because. You know, you don't want to call the whole chain, you know, all the way up to wherever it goes, up to and including over the network for something else. But I've had mocks and stubs get out of hand, where it starts to get hard to keep track of what is, I guess, there by default and what's being mocked out. So how do you keep all of that straight?
DANIEL_CALDAS: Yeah, so that's a problem that I've been debating myself, especially when you have this, like, not big modules, but that have like a huge bunch of dependencies that you just open this JS file and you see the first 50 lines that are imports or something like that. And then you have a test file and you need to either mock all of them or mock some of them but somehow it ends up like being hell. One thing to do here is that I found useful myself is like have yourself a bit of like organization organization is enforce or at least try to put in place rules like sorting the imports like alphabetically and then trying to follow the same rule whenever you are defining the mocks. This might seem like very simple, but it saved me a lot of time when I was debugging something and trying to understand what's mocked and what's not mocked. So just having these little tricks and organize yourself can save you like a bunch of time, can save you a lot of time to you and your team. Then to actually debugging and like understanding, like is this module being stopped? It's not like what's going on. For those cases, what I would advise is like, whenever like you have a huge file, a huge test file and you have no idea what's the scenario there in terms of what's being stopped or not, run one of the test cases. If you're using VS Code, configure the debugger with the Jest extension, which is pretty cool. Set up a breakpoint in whatever line you can. Look at the modules that appear on your scope. So you look at the file and you see. And looking at each one of the modules, you can see, okay, this guy has like mock functions inside. And then you can go as deep as you want and you will understand then. And it's just not an assumption. You will really know for sure that, okay, this guy is a stub because someone is actually like stubbing this reference. And this one for sure, I'm secure that there is being stubbed. Or you see that for instance, oh, after all my stub is not working. I'm ending up calling the real implementation and why is that? And then you go up in your file and you realize, oh, okay, this mock or this, this stuff that I set up is like, it's not set up properly. And it just realized the stuff when you, when you use a debugger, even you just analyze the scope of, of the test file. I found this like pretty useful in my opinion. Yeah.
CHARLES MAX_WOOD: And one other thing that I'm running into or thinking about is just when you run your tests. So some people they do like test-driven development. So they write a breaking test, then they run the test, make sure it fails. And then they write code to make it pass. And then they run it afterward and see that it passed. And for other people it's, I write my test, I write my code and then I write my test. And then I just run it afterward. Some people just run the tests on the things that they've changed. Other people run all the tests before they commit. And then you've got CI and CD. So where are you running tests and what kind of environments?
DANIEL_CALDAS: This is a fairly large topic. I'll try to give a little bit of input around my experience, both locally and then trying to understand the surroundings of whatever changes you've performed on the code base. And also later on in the continuous integration process that your project might have set up. First, going on to TDD, I've been doing it sometimes. I'm not quite sure if I'm doing it properly, but it helps in certain cases. And those cases are the ones where like, I'm coding something and I clearly know what's the expectation. And this is mostly around handling data and writing stuff like peer functions. So for TDD, like you have a like you have a clear goal in mind, you describe your tests, you describe your, all your output looks like, and it's pretty, pretty straightforward to see our tests fail and then you just write some codes and you try to achieve parity, uh, in a few iterations and with Jest, it's pretty cool because you can pretty much start it just one file with a common line or with the Jest VS code extension. You can just run on a single file and just stay focused there. But if you're talking about writing tests, unit tests for like stuff like interaction, like rendering components, clicking stuff around and seeing side effects. I don't think I ever did TDD in this kind of situation because what I mostly do as a front-end developer is like I open the browser and I need to see things happening. Otherwise, I won't feel sure. So I don't know if it's still like I have a very primitive mindset around development, but it just doesn't feel as productive if I'm trying to do like, I don't know, mounting a component and then doing a shallow rendering and then clicking on a button and then going back to the component and writing some click handler and then doing some logic. So it just doesn't feel as natural for me, at least in my opinion. So that's like my perspective around like TDD and how it can speed up your development. But also if you go like an extra mist about TVV and just like say, I'm going 100% and full steam on TV, then yeah, I think you might get stuck in, especially when getting closer to the UI. Then in terms of like, do I run all the tests or do you target specifically some parts of the codeways that you need to check? Well, it really depends and varies a lot with what kind of changes I'm introducing the codeways. If it's like super tiny and super focused, I will probably feel comfortable in running the tests against that module or even that specific file. And that would be okay for me. But usually when I start doing stuff that is more like horizontal and kind of touches here and there and goes goes around the code base, then just for having full peace of mind and be in peace and push and make things running in CI and having almost sure that everything is going to stay green at the end. Then in those cases, I run just the full project or at least the full sub-module. It really depends on the dimension of your code base as well because sometimes it gets take up to minutes. So you can also measure that and see whether you really want to just spend that time like watching the test cases go rather green while you can focus on something else. Or if you just like go ahead and just push and just let the CI take over. Then in terms of continuous integration, like I'm not really an expert, but for me it's about running everything like fresh and clean with no exceptions and not like very sophisticated kind of mechanisms like for instance I saw some projects that like could detect changes in some terminal modules and just run the test for those modules because they would be an 100% safe and confident that those changes wouldn't impact other modules that don't depend on those make sure in the CI, just make sure, at least in my personal projects, to like run everything and make sure that I get everything green, at least in terms of like assertions. Cannot say the same for coverage, unfortunately, that's a bit more tricky to get there. But yeah, at least getting everything green is the prime goal, I would say.
CHARLES MAX_WOOD: Nice. Just one more question that I have. I feel like I've kind of monopolized asking the questions and diving into this, but I find it very interesting. And I feel like testing is one of those areas that doesn't get talked about enough. So we've talked a whole bunch about Jest and about, you know, how to do testing with Jest. The thing that I see most done with Jest is unit tests. One thing that I'm curious about is do you run other kinds of tests in line with your Jest testing? So for example, do you pull in Cypress.io and do end to end or automated UIs? Do you pull in? Or do you use JS to do some kinds of like integration testing or, you know, full feature testing or component testing or things like that?
DANIEL_CALDAS: Yeah. Here I'm going to talk about my experience in the open source project that I mentioned, the Reacti 3 graph, and then also on like a bit of my professional experience around this overall test setup landscape, let's say.
CHARLES MAX_WOOD: Sounds good.
DANIEL_CALDAS: So for the open source project, I set myself kind of a strict boundaries in terms of what's going to be tested. I use Cypress, by the way, to do the end-to-end automation. So I kind of got a bit strict on what I would do in unit testing and what I would do with end-to-end testing. So, and what I do with Jest in this project is that I have no tests whatsoever for the components except for this just simple let's call it smoke test just to render the component and do an assertion on the snapshot. So the output that I get from the render, I just do a match snapshot. And that's as far as I'll go in terms of the UI. But then in terms of all the modules that are all this logic that builds small configurations around client data that is passed, and then you have a bunch of configs that toggle in and out features. So all of this, I tried to cover it in terms of testing it properly with Jest. So this is more on the business logic and going into each file and trying to look at the entry points and testing those APIs properly and making sure that I'm getting the most deterministic behavior that I can get. But then in terms of functionality, I go all the way to the end-to-end tests. And I don't really see the benefit of... Maybe I'm wrong here, but if you do UI component testing and you do like this... The shallow rendering of a component, and then you do some click actions here and there, and then you perform some assertions on what happens in terms of side effects in that UI component. And then you go in the end-to-end tests, and you perform the same steps. You go and you click on the same stuff and you assert for the same side effects, I think it's just not very productive. And there's some redundancy here, right? Because you're kind of repeating yourself at some level. And I'm not really sure if it's really worth it too, but for sure, it brings you more security and it brings you more safety and more stability. You cannot take that away. Then talking more about end-to-end tests. It's this article and the next one, I was reading a bit around the, how a product or like how an application should go about testing. And there's this like the pyramid, I think it's called pyramid of testing, if I'm not mistaken. Something around of like, where do you need to put more effort and all fast series versus all fast series. So, and what you get is like, okay, you should have like a bunch of unit tests because they are, they are fast to write and you should have as much coverage as possible. Then as you go up in the pyramid and you get more narrow, you should have just a few end-to-end tests and covering as much as possible end-user behavior scenarios. But bear in mind that these tests are usually way more expensive to write and they are way more expensive in terms of time. They are very time-consuming because running, sidepress, running something Selenium based is not going to be as fast as running a component test on Jest that you just like you use GSTOM and everything is JavaScript and is running on nodes and you don't have any browser drivers in the process or any kind of like that. That is expensive stuff just stays out of the picture. So in that sense, I think it makes sense that you just try to be as much pragmatic as you can in terms of what end-to-end tests you want to write and avoid repetition and just avoid writing useless kind of tests. Like, challenge end-to-end tests in ways that you ask yourself, is this scenario really a thing that I should be testing behavior-wise? Because if you're talking about companies like where I work like Trivago, which is like B2C, and YouTube basically releases every day, maybe more than one a day. And you want to deliver stuff fast because a release can take up to several hours from the QA process until rolling out all the servers, until then scaling worldwide while data centers and all this bunch of processes are involved. So you want to make sure that you stay as as much time efficient as possible in terms of automation. That's the thing that I think companies look into. But sometimes these barriers that I was talking about, like in my personal, like the open source project, I think sometimes it matters or probably they are not communicated properly. And then you overstep into some areas that you don't want to. Maybe it's not the goal of QA team or whatever is the architect that's behind the decision of setting up such a test environment or test ecosystem around your product. So yeah, I think in that sense, you should find your balance and not going all the way to just having end-to-end tests or just having unit tests, but try to find a balance and measure things like effort and time. Yeah, time in terms of like how time consuming it is to run this test in a, in a like a continuous integration environment and like just pull out this thing.
CHARLES MAX_WOOD: Yeah, we had a conversation on React Native Radio, which I recorded right before this. And we were talking about, you know, essentially where does the QA role end and the developer role begin? And a lot of that is defined by the company and yeah. So then it's, okay, what's the ROI? What's my role? What's their role? how are we defining that? And then in the places where we see that they cross over, are we making sure that we're not duplicating effort? It's definitely a consideration that you need to make as far as what the ROI is. So if I put in a ton of time and it's not going to keep me from putting bugs in my code, then it's probably not worth it. If it's a negligible amount of time, it's not going to slow my test down and it's going to, you know, catch stupid errors that I'm prone to make, then it's probably worth it, right? And then if you get into the nuance in between, then it's like, okay, is this worth the trade off or not?
DANIEL_CALDAS: Yeah. I think it just gets a bit harder if you have like super large organizations. And these days they are not only large, but they are as well distributed. So like in my case right now, people in the U S throwing out commits into the, the repos. And then during the next day while they are asleep, we go and we throw a few more commits there. And yeah, it's super difficult to keep these things aligned. And there needs to be a lot of effort, like in a lot of communication around these things in order to make sure that we don't overstep each other.
CHARLES MAX_WOOD: Yep. All right, well, we're getting toward the end of our time. Is there anything else that people should know about Jest or about you?
DANIEL_CALDAS: So about Jest, I would say that especially if you are starting with JavaScript and frontend, just don't think too much about the library you're going to use because at the end, you're probably going to end up using Jest. It's more important at a beginner stage to have unit tests and to decide like what is the proper testing framework that I should be using. There are a bunch of other choices that you'll struggle way more than like to choose your testing library. And about me, if you want to check out my open-source work, I just go on GitHub, search for Daniel Caldas or search for React D3 Graph. It's a pretty cool project that I've been putting a lot of effort into. And I just like to get it out there and people commenting in people like requesting new features or even bringing on board more contributors. And yeah, if you want to follow me on Twitter and all other social media. Also, also there. Yeah.
CHARLES MAX_WOOD: Cool.
Hey folks, this is Charles Maxwood. And over the last few years, I've gotten to know a lot of great people within the Microsoft community and specifically in the.NET area. One of our guests from JavaScript Jabber, Sean Clabo, actually reached out to me and said he wanted to start a show on.NET. And there are a ton of people out there that I feel like sometimes get neglected in the.NET space. So if you're one of those folks, you've been listening to maybe one or two of the other.NET focused or Microsoft focused podcasts for a while and thought. Well, where's the devchat.tv style podcast for me in.net. You can find it. It's at adventures in.net. net is spelled out D O T N E T adventures in.net.com. Go check it out today.
CHARLES MAX_WOOD: All right. Well, let's go ahead and do some picks. AJ, do you want to start us off with picks?
AJ_O’NEAL: No, but let me think about it for a second.
CHARLES MAX_WOOD: You're good. Well, anyway, I've got some picks ready unless Amy does. I do go ahead, Amy.
AIMEE_KNIGHT: I'm going to pick this short article that I found on Hacker News, just because it has good images, I think, to understand stuff. So the difference between fault tolerance, high availability, and disaster recovery. And for fault tolerance, he has a plane with four propellers and then high availability. It's a Jeep with the spare wheel. It's a huge wheel. And then disaster recovery, he's got a guy ejecting from a plane. So, that's pretty good. Uh, that's going to be my pick for today.
CHARLES MAX_WOOD: Nice. AJ, you ready? Or should I share mine?
AJ_O’NEAL: Yeah, yeah, I'll go. Okay. So I think I'll pick two things. One, the Rubin report. Now I am not, uh, I'm more, I don't know what I am politically, but what I do know is that this is a person that there's a lot of. Uh, opinions and beliefs that he has that I disagree with, but he's so civil and so seemingly unbiased in his approach as he interviews people. And as he discusses topics that I can't help, but like him, like, I don't know. It's, it's, it's one of those those beautiful things where you can, you can disagree with someone. And like, of course I'm not in the room with them. I haven't met him in person or anything, but I've been watching some of his stuff. And, you know, and he's, he interviews very controversial people, uh, like for example, Donald Trump Jr. And, and whatnot, but he's just so, uh, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss, ss. And one of the people that he interviewed was on a topic that I feel is super important. Her name is Lindsay Shepherd. And this, the, the stuff that went down happened a couple of years ago, but basically she's somebody on the far, like progressive far left, somebody that I really just don't have a lot in common with, but she started getting, uh, harassed by radicals at her university and just weird stuff happened. And, I mean, fortunately, things sided in the favor of the law. And what I believe is correct, which is to allow people their freedoms of expression within bounds of not being harassing or violent. And I'll just link to that interview if I can find it real quick. Because I think that there's some things happening that I wasn't aware of before, something in the political landscape is happening that is strange and it's taking hold and this idea of silencing people or using violence to enforce ideas rather than debate is something that I think is concerning and that's what this interview revolved around.
CHARLES MAX_WOOD: Thanks AJ. I'm going to pick a few things. I've been picking Christmas movies. I'm going to do it for the next probably another week or two just because it's kind of part of what I really enjoy in the holiday season. And so, yeah, I'm gonna pick a few. Now, I am curious if anybody here knows off the top of their head, what movie the song White Christmas is originally from?
DANIEL_CALDAS: No clue.
CHARLES MAX_WOOD: It's not from the movie White Christmas, which is actually one of my picks. So White Christmas, it's a movie with Bean Crosby. It has the song in it, but it's not the movie that it's originally from. Has Bean Crosby and Danny Kay. It's an awesome movie. I just really, really enjoy it. Like I said, it was made in the 50s, very Christmas-focused movie. It has singing and dancing and performing. And anyway, I just, I really, really love it. So I definitely check that out. The movie that it's originally from, the song White Christmas is from Holiday Inn, also has Bing Crosby in it, incidentally, was made in 1942. And so it's about 12 years older than White Christmas. Anyway, it's a terrific movie too. It's about these guys that come back from the war and they basically open up kind of a bed and breakfast inn. They have different holidays celebrated through it. Anyway, I really, really love that movie too. So between the two, Holiday Inn and White Christmas, two just terrific movies. And yes, they are rather old movies. I only have one other movie that I'm intending to pick that is newer than 1980. And I'll probably pick it here in a week or two. And it's, it's the one that I absolutely positively have to watch every year. So I'll give you that as a hint. And then finally, like I said, my book is out, the max coders guide to finding your dream developer job, it's on Amazon. I'll put a link here in the show notes and you can definitely just go check that out. I think I've set the price to like 2 99. If you get it the day after tomorrow, as we record this, I think I had it at 99 cents, but yeah just putting it out there and hopefully it helps a few people find jobs. I am working on a course that's going to go with it. The audio book should be up in a week or so and the print book should be available in about a week as we record this. So I think this comes out in like a month. So all of that should be available to you by it, by this point. So just go into, uh, Amazon and just to do a search for the max coders guide to finding your dream developer job. Or I've been finding it cause I keep looking it up. Uh, just look it up on max coders. And if you type in Max Cutters, then you should be able to find it. And yeah, those are my picks. Daniel, do you have some picks for us?
DANIEL_CALDAS: Well, talking about Christmas, I don't know if that's a thing in the US or not, but in Portugal, it's kind of mandatory that you watch Home Alone.
CHARLES MAX_WOOD: Home Alone.
DANIEL_CALDAS: Yeah, it's a classic. It goes on in here, like at least on two or three TV channels, they are public, like free to consume. I think it's kind of a meme at this point in time, but we still watch it. And that's, that's for sure.
CHARLES MAX_WOOD: Now do you watch Home Alone or Home Alone 2 or?
DANIEL_CALDAS: Well you kind of get the chance to watch them all. They go in sequence. So I like the classics. I stick to the Home Alone. Normal Home Alone 2 maybe if I have time, but yeah, definitely the first one.
CHARLES MAX_WOOD: Yeah. So every year I buy my wife a Christmas movie. Yeah. What's funny is, is I got her the Home Alone movie set. And when I bought it, I was like, there's a Home Alone three. And there is, it looks like it's not with any of the same actors as Home Alone one and two, but yeah, but you can stream it all over the place. Home Alone one and two came out in 90, I think 1990 and 1992 and Home Alone three was like 1997. So it's Yeah, anyway.
DANIEL_CALDAS: It's not a classic as the ones you mentioned, but.
CHARLES MAX_WOOD: Yeah, not quite as old.
DANIEL_CALDAS: Not quite as old, but it's getting there.
CHARLES MAX_WOOD: Different flavor, but yeah, it's Christmas. Yeah. All right, good deal. Well, let's go ahead and wrap this up. Thank you for coming, Daniel.
DANIEL_CALDAS: Well, thank you for having me. It was a pleasure.
CHARLES MAX_WOOD: All right, folks, we're gonna wrap it up. We'll be back next week and until then, Max out.
AIMEE_KNIGHT: Bye.
AJ_O’NEAL: Adios.
Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. Deliver your content fast with Cashfly. Visit c-a-c-h-e-f-l-y dot com to learn more.
JSJ 411: Unit Testing Jest with Daniel Caldas
0:00
Playback Speed: