Register to get access to 15+ free programming courses with interactive exercises

Jest JS: Automated testing

When you end up with many tests and test files, new questions start to arise. How do I group the tests? How do I run all the tests in one directory? If there are a lot of them and they're lengthy, is it possible to run them in parallel?

Special test frameworks are used to address these issues. They help you to structure your tests and provide many useful features, such as convenient output formatting. We'll get to know most of these features later in the course. In the JavaScript world, the most popular framework is Jest (by Facebook). Incidentally, it's the framework we use to test all the practice assignments on Hexlet.

Now let's try to create an npm project from scratch and add tests.

Setup and startup

Create a directory called hexlet-jest somewhere on your computer. Go into it and execute this command:

npm init

Answer all the questions from the project initialization script that runs. Make sure that src/index.js appears in the project root.

// This function reverses the string passed to it
export default str => str.split('').reverse().join('');

Jest is a regular npm package that you plug into the developed project locally. Jest is only needed during development, so it's best to install it in the devDependencies section:

# In the project directory
npm i --save-dev jest

For Jest to work correctly with the module system, add the following option to package.json:

  "type": "module"

Jest expects the tests to be in the __tests__ directory usually located at the project root. You can create any structure within this directory, and Jest will find all the tests that are there. Test files should be named in this format: <name>.test.js. Where <name>, as a rule, corresponds to the name of the module being tested.

Let's write our first test. Create __tests__/index.test.js with the following content:

import reverse from '../src/index.js';

test('reverse', () => {
  expect(reverse('hello')).toEqual('olleh');
  expect(reverse('')).toEqual('');
});

We'll analyze the structure of this file later, but for now, let's try to do a runtime test:

# Jest supports ECMAScript modules in experimental mode
NODE_OPTIONS=--experimental-vm-modules npx jest
 PASS  __tests__/index.test.js
  ✓ reverse (11ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.166s
Ran all test suites.

Hooray! The tests were successful.

Structure

Let's look at the test file again:

import reverse from '../src/index.js';

test('reverse', () => {
  expect(reverse('hello')).toEqual('olleh');
  expect(reverse('')).toEqual('');
});

Jest provides two global functions for testing: test and expect. You don't need to import them because Jest adds them to the global context.

The test function helps you describe a specific test and its assertions. There can be any number of test functions. Its first parameter is an arbitrary string, the test description. This string is then displayed on the screen when running tests to simplify debugging.

NODE_OPTIONS=--experimental-vm-modules npx jest
 PASS  __tests__/index.test.js
  ✓ reverse (11ms) # test name

The second parameter is the function containing actual tests. Note that this code is not executed immediately. The test function adds it inside Jest, which decides how and when to run tests. This allows for various optimizations, such as running tests in parallel.

The most unusual thing about this code is the checks themselves; Jest uses "matchers", statements that have a special structure resembling a reference to an object. The general principle of matchers is as follows:

  • The expect() function is called, to which an actual value is passed
  • A suitable matcher, such as toEqual, will be called on the result returned by expect()

Code with matchers is similar to ordinary sentences in English. This is done on purpose so that even non-programmers can read them:

// the result of the expression reverse('hello') is expected to be 'olleh'
expect(reverse('hello')).toEqual('olleh');

You'll learn more about matchers in the next lesson.

One of the nicest features of Jest is the way it displays messages about failed tests. Try to make a mistake in the original function and run the tests again:

 NODE_OPTIONS=--experimental-vm-modules npx jest
 FAIL  __tests__/index.test.js
  ✕ reverse (9ms)

  ● reverse

    expect(received).toEqual(expected) // Object.is equality

    Expected: "olleh"
    Received: "o|l|l|e|h"

      3 | test('reverse', () => {
      4 |   const str = 'hello';
    > 5 |   expect(reverse(str)).toEqual('olleh');
        |                        ^
      6 | })
      7 |

      at Object.toEqual (__tests__/index.test.js:5:24)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.683s
Ran all test suites.

This output shows not only the expected and actual value, but also the source code of the test file, showing what the actual check was. This is an incredibly useful feature that greatly speeds up analysis of test results and helps with debugging.


Do it yourself

  1. Follow all of the steps in this lesson
  2. Upload the code to GitHub

Example of a fully configured package: https://github.com/hexlet-boilerplates/nodejs-package


Recommended materials

  1. Jest
  2. Test blocks (describe)
  3. JS: Setting up environment

Аватары экспертов Хекслета

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs

From zero to a developer. Refunds in case you won't get a job

Frontend Developer icon
Profession
New
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions

Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.