DEV Community

Cover image for Adding Jest tests to a project
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Adding Jest tests to a project

Now that we are talking about testing, let's try out Jest, a pretty well-used testing framework for JavaScript.

I've been using Jest for the past couple of months, finding it really powerful so far.

There are some other really great frameworks out there, and choosing one comes down to flavor and needs.

For this article, I'll use a simple JavaScript project as our basis.
It will have a determination script to determine if certain statements are true or false.

You can download the starting point from GitHub.

Validating our function

You can see the determine.js function in the main folder.
This is basically our app. It's used to determine if a variable is a number.

In the most basic case, it should perform the following tests:

isNumber(123);
// Should be true

isNumber('abc');
// Should be false
Enter fullscreen mode Exit fullscreen mode

We first have to add Jest to our project to make this testable.

npm install -D jest
Enter fullscreen mode Exit fullscreen mode

The code above will install the jest package in our dev dependencies.

Now we should modify our package.json to include a testing command.

"scripts": {
    "test": "jest"
}
Enter fullscreen mode Exit fullscreen mode

The cool thing about Jest is that it can fire automatically on any files it deems testable.

By default, it can run on the following files:

  • .js files inside __tests__ folders
  • .test.js files inside your project
  • .spec.js files inside your project

For now, let's add a determine.test.js file. This makes sense as we have our determine.js file as our basis.

To start the file, we have to import our function first.

const { isNumber } = require('./determine');
Enter fullscreen mode Exit fullscreen mode

Then we can define tests. Each test is an isolated scope that can pass or fail.

Let's start by adding a test made to expect the right answer.

test('Validate a number', () => {
  expect(isNumber(1)).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

We start by defining the test, which holds a string (the name of the test) and executes a function.
The actual test states:

Expect -> function (variables) -> to be true

I really love how Jest made these super human-readable and understandable.

We ask for the function isNumber to be true when we pass the number one to it.

We can now run the test by invoking the following command:

npm run test
Enter fullscreen mode Exit fullscreen mode

Running tests in Jest

And as you can see, our test is succeeding.

Let's step up our test and add a failing test, but leave the same evaluation.

test('Invalidate a string', () => {
  expect(isNumber('ABC')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

We use the same test but pass a wrong number, so the test should fail.

Failing tests

And it does fail, which is expected!
So let's modify the test case to evaluate a false value.

test('Invalidate a string', () => {
  expect(isNumber('ABC')).toBeFalsy();
});
Enter fullscreen mode Exit fullscreen mode

Our test will succeed, but we still check for a failed value!

The completed test can be found here on GitHub.

Conclusion

Although this is a very straightforward test, it can be super important. Let's say we modify something in this isNumber function. Our test will now quickly show something went wrong.

I'll be writing a bit more about writing some particular test cases and showing you how you can use and leverage Jest.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (8)

Collapse
 
lexlohr profile image
Alex Lohr

While jest is full of features, it is also rather large, opinionated and slow. If you need the same features, you should consider vitest and if you can do without and want your tests to run even faster, try uvu.

Also, good example on how to break your tests. Make sure every test is red at least once to avoid false positives.

Collapse
 
peerreynders profile image
peerreynders

I think SvelteKit adopted uvu.

I suppose Solid.js is using Jest simply because of contributor skill prevalence.

A pet hypothesis of mine is that Jest's feature set encourages testing to drift from "microtesting" to "integrated testing" (should be covered by end-to-end testing) which fails to impose the correct design pressures on the components.

Collapse
 
lexlohr profile image
Alex Lohr • Edited

Solid-start (basically Solid's SvelteKit) is currenlty planning its test suite; since I'm the resident Solid.js unit testing guy, I suggested either uvu or vitest.

Update: vitest it is.

Collapse
 
jakecarpenter profile image
Jake Carpenter • Edited

Thanks for bringing my attention to vitest. I’m going to take a look at it to see if it can replace jest in our Expo RN project. Jest-expo has a ton of problems.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Nice tip!

I'll write it on my research list, sounds pretty amazing.
Does it easily switch from Jest to vitest?

Collapse
 
lexlohr profile image
Alex Lohr

The API is the same and the configuration is similar to vite and really simple.

Collapse
 
liviufromendtest profile image
Liviu Lupei

I enjoyed reading this, you have a great way of explaining things.
You keep it simple, but without losing details.

My personal opinion is that folks should know that having Jest tests that pass does not mean that their web app will work as expected.

A browser is more than just a JavaScript interpreter, and the rendering engines from browsers are more different now than they ever were.

Safari currently has a 20% market share, and it keeps growing. I'd say cross-browser testing is more important and relevant than it ever was.

Here is what happened to us when we didn't have full test coverage in Safari.

TLDR: Jest tests are useful, but you also need to have functional end-to-end tests, that actually perform the actions from the perspective of a real user.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Very good point and indeed one should never solely rely on this kind of testing as it's very one-sided