Professional WorkflowExtra· 45 min read

Automated Testing with Jest

Stop checking your code by hand every time. Automated tests are small programs that prove your functions still work — run them in one command, catch bugs before users do. A standard job-ready skill.

What you will learn

  • Explain why automated tests matter
  • Read and write a test with Jest
  • Understand the arrange-act-assert pattern

Why write tests?

Right now, when you change your code, you probably check it by hand — open the page, click around, see if it still works. That is slow, easy to forget, and gets worse as your project grows. An automated test is a tiny program that checks your code for you: it runs your function with known inputs and confirms it gives the expected output. Run all your tests with one command, any time, and instantly know if something broke.

Jest is the most popular JavaScript testing tool. It runs in Node.js (not the browser), so the examples below are run from a terminal, not a live preview. The idea is simple: keep your real code in one file and your tests in a separate file that imports and checks it.

Your first test

Say you have a simple function to test. We put it in its own file and export it so the test can import it.

The function under test, exported
// math.js — the real code we want to test
function add(a, b) {
  return a + b;
}
module.exports = add;

Now the test file. Jest gives you two key words: test() describes one thing you are checking, and expect(...).toBe(...) states what you expect. Read it almost like English.

A Jest test file with two checks
// math.test.js — the tests for math.js
const add = require("./math");

test("add returns the sum of two numbers", () => {
  expect(add(2, 3)).toBe(5);
});

test("add works with zero", () => {
  expect(add(0, 7)).toBe(7);
});

Reading the first test in plain words:

  1. test("...", () => { ... }) declares one test with a description and a function holding the check.
  2. expect(add(2, 3)) says "I am about to make a claim about the result of add(2, 3)".
  3. .toBe(5) is the claim: that result should be 5. (.toBe is called a matcher — it compares actual vs expected.)
  4. If add(2, 3) really returns 5, the test passes (green). If it returned something else, the test fails and Jest shows what it got vs what it expected.

You run the tests with one terminal command, npx jest:

Run the test suite
# Run all *.test.js files
npx jest

Note: Output: PASS ./math.test.js ✓ add returns the sum of two numbers ✓ add works with zero Tests: 2 passed, 2 total (Green ticks mean your code behaves as expected.)

What a failing test looks like

Failing tests are not bad news — they are the whole point: they catch a bug the moment it appears. If add had a mistake (say it multiplied instead), Jest would tell you exactly what went wrong:

Note: Output (if add were broken): FAIL ./math.test.js ✕ add returns the sum of two numbers expect(received).toBe(expected) Expected: 5 Received: 6 (Jest pinpoints the failing test and shows expected vs received — so you fix it fast.)

Common matchers and the arrange-act-assert pattern

Beyond .toBe, Jest has many matchers for different checks:

MatcherChecks that…
.toBe(x)Value equals x (for numbers, strings, booleans)
.toEqual(obj)Objects/arrays have the same contents
.toBeTruthy() / .toBeFalsy()Value is truthy / falsy
.toContain(item)An array or string contains the item
.toThrow()A function throws an error

Well-written tests follow a simple three-step shape called Arrange–Act–Assert (AAA): set up the data, run the thing, then check the result. Here it is applied to a filter-based function:

Arrange, Act, Assert in one test
// returns only the passing scores (>= 40)
function passing(scores) {
  return scores.filter(s => s >= 40);
}
module.exports = passing;

// --- passing.test.js ---
const passing = require("./passing");

test("keeps only scores of 40 or more", () => {
  const scores = [55, 30, 40, 12];     // Arrange: set up input
  const result = passing(scores);      // Act: run the function
  expect(result).toEqual([55, 40]);    // Assert: check the output
});

The three comments map to AAA: we arrange the input array, act by calling passing(scores), and assert with .toEqual([55, 40]) that only the scores ≥ 40 came back. Note we use .toEqual (not .toBe) because we are comparing the contents of an array, not a single primitive value.

Note: Output: PASS ./passing.test.js ✓ keeps only scores of 40 or more Tests: 1 passed, 1 total

Tip: A good first habit: every time you write a function, write at least one test for it — a normal case and an edge case (empty input, zero, a missing value). Tests are a safety net that lets you change code confidently without fear of silently breaking something.

Q. In Jest, what does expect(add(2, 3)).toBe(5) do?

Answer: expect(...) wraps the actual result and .toBe(5) is the matcher asserting it should equal 5. If add(2, 3) returns anything other than 5, the test fails and Jest reports expected vs received.

✍️ Practice

  1. Write a multiply(a, b) function and a Jest test that checks multiply(3, 4) is 12.
  2. Write a test using .toEqual to check that a function returns the array [1, 2, 3].

🏠 Homework

  1. Take one function from an earlier project (e.g. a grade calculator or a total-price function) and write two or three Jest tests for it: a normal case and at least one edge case.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →