So many entry level developers nowadays are coming from non-traditional backgrounds (like me!), i.e. coding bootcamps, self-taught experiences, and that is amazing and wonderful. However, one thing that is often lacking in our preparation is a focus on testing; this is a shame because it is actually quite an important skill to know. You will see it as part of many job requirements and you will definitely encounter the question as to how you’ve tested your code during job interviews. Getting at least mildly familiar with testing will definitely give you a bit of a leg up when applying to jobs, as it will set you apart from many other developers that haven’t even dipped their toes into the testing pool.
First step, though, is to create a directory that will hold our code file(s) and our testing files.
validateCode.js file, we are going to add some code that we will want to test and we will export that code into a testing file. We’ll get to that in a second.
In order to use Jest, we first have to run a command in our terminal:
npm init -y
-y is added to initialize our file with all the default values. Once we run that command, that gives us our starting point,
Now we actually want to install Jest itself, which we haven’t done yet, hahaha. This is done via another command in the terminal:
npm i --save-dev jest
Side note: we are saving this as a development dependency because we only want to use this testing library in development to make sure everything runs.
Once that is done downloading, we can go into our
package.json and change our test script to simply say “jest”.
That is all that is needed to set up Jest for testing! Now in the terminal, we simply type in
And that will run Jest and all of our tests! But wait….
Of course it fails! We don’t have any tests!
To get started creating tests, all you need to do is create a new file, give it the exact same name as the file you want to test, followed by
.test.js. In our case, if we are testing code in the
validateCode.js file, our test file will look like
Inside of this file, we need to import our function. But first we need to write a function and export it! So let’s get back to our
In this file, I’ve created a function,
validateCode(), that is going to tell us whether two words are anagrams of each other; the function accepts two strings and outputs either true (if the words are anagrams) or false (if they are not anagrams). The function also makes use of a helper function,
buildCharMap(), which takes an individual string as an input and creates a hash map for that string (hash map here means an object whose keys are the letters in the string and values are the number of times that letter is found in the string).
Notice at the bottom of the file, I have the line
module.exports = validateCode. This is important! This line allows us to export the function to be tested…into the test file!
How do we call on that function in the test file? Like so:
And nowwww we are finally ready to write our first test!
We want to write a test that shows our function works, right? So what does it mean for our function to ‘work’? It means that if we give our function two words that ARE anagrams, our function will return TRUE…and if we give it two words that are NOT anagrams, our function will return FALSE.
In order to write a function with Jest, we use a function called
test(). The very first parameter to this test function is just a string of what the test is doing…you write what you want to test and this actually show up inside the console when we run the test. The second parameter is a function which gets called to run the test; inside the function, we need to make sure our expected result actually happens. The beauty of using Jest is that there are functions built in that make the code for testing less bulky to write. These test functions are called
So the code above is what a completed test looks like. We pass in our function to be tested (in our case,
validateCode) to the
validateCode function takes in two arguments, so we pass those in…and what do we expect to happen? Well, if we pass in “silent” and “listen”, those are anagrams, so we expect the output to be
Now if we run
npm test in our console, we get
So let’s break down that
expect() function really quick. What that is saying is that we expect whatever we pass into the first part (before the period) TO DO SOMETHING related to the second part (after the period). There are actually quite a few different functions we could use for that second part, like .
.not.toBe(), etc. (You can see a good list of possibilities here).
All that sounds great, but you may have noticed a problem. At the moment, it’s hard to tell which parts of our code are being tested. How can we be sure that ALL our code (all our functions, all our lines) gets tested?? This is something that absolutely needs to be addressed in order for your tests to have any meaning.
Well, there is a solution with Jest! If we go to our
package.json file and change it from simply
and then run
npm test, we can get a coverage report!
NOW we can see that our “passing test” only gave us a partial picture of what was going on. Yes, we had our test passing, but we have lines of code that aren’t being covered by the test we wrote! Conveniently, our console coverage report tells us which lines of code are not being covered. Even MORE convenient, however, is the fact that we can check a more visually appealing coverage report in our browser!
If we take a look at our file tree, we notice that a new directory has been added, called
INSIDE of that directory, there is yet another directory which contains a whole bunch of files…and what we are looking for is an
Copy that path into your browser, and you will see:
OOOOOH. Look at that bar! You can see that not all of our code has been tested. And if you click on
validateCode.js, you will see which lines exactly have not been covered. Hint: the ones in red (or pink? I think it looks more pink, tbh).
Of course this makes sense! We tested a case where two words were CLEARLY anagrams, but we didn’t test any cases where they were NOT anagrams. So let’s add two more scenarios and run
Aha! Look at all that GREEN. Let’s also take a look at our browser report:
No more red (or pink, whatever).
One last thing to mention. Remember that I have that helper function,
buildCharMap() in my
validateCode.js file. Why doesn’t that show up as red? Does that mean it IS being covered in my test even thought I don’t explicitly say to test it??? Hint: the answer is yes. The reason for that is I call
buildCharMap() in my
validateCode() function and so those lines ARE BEING TESTED!
And so ends our brief but hopefully helpful foray into testing with Jest. The more tests you write, the more coverage reports you examine, the faster you will get at understanding what tests will be appropriate to give meaning to your code.