Writing Your First Test
Objectives
By the end of this lesson, you should be able to:
- Install Jest and run a test file
- Structure tests with
describeandit/test - Write assertions with
expect, and read a failing test’s output
💡 Why this matters: Every “Try It” in this course so far involved manually running a script and reading its output by eye. That works, but nobody reruns every manual check by hand before every change, Jest automates exactly that check, and reruns it in seconds, as often as needed.
⚠️ A note on verification: every snippet and every output in this lesson was actually run.
Installing Jest
npm install --save-dev jest
Jest is a development dependency, --save-dev, it’s needed while building the application, not when running it in production.
A Function to Test
// math.js
function add(a, b) {
return a + b;
}
module.exports = { add };
Writing a Test File
// math.test.js
const { add } = require('./math');
describe('add', () => {
it('adds two positive numbers', () => {
expect(add(2, 3)).toBe(5);
});
it('adds a negative and a positive number', () => {
expect(add(-5, 3)).toBe(-2);
});
});
Jest automatically finds files ending in .test.js (or inside a __tests__ folder), no separate configuration needed for a project this size. describe groups related tests under a shared label, it (an alias for test) defines one individual test case, with a description of what it checks. expect(value).toBe(expected) is an assertion, it checks that value strictly equals expected, and fails the test if it doesn’t.
Running the Tests
npx jest --verbose
PASS jesttest/math.test.js
add
✓ adds two positive numbers (3 ms)
✓ adds a negative and a positive number (1 ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.313 s
Both tests pass, --verbose prints each individual test’s description, useful while learning, often left off once a suite grows large and only failures need attention.
Reading a Failing Test
test('a deliberately wrong expectation', () => {
expect(add(2, 2)).toBe(5);
});
FAIL jesttest/fail.test.js
✕ a deliberately wrong expectation (4 ms)
● a deliberately wrong expectation
expect(received).toBe(expected) // Object.is equality
Expected: 5
Received: 4
2 |
3 | test('a deliberately wrong expectation', () => {
> 4 | expect(add(2, 2)).toBe(5);
| ^
5 | });
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Jest points at the exact line, shows what was expected versus what was actually received, and marks the overall run as failed, exactly the information needed to fix either the code or the test, without stepping through anything manually.
Adding an npm Script
"scripts": {
"test": "jest"
}
With this in package.json, npm test runs the whole suite, the standard command any Node.js project’s tests are run with, regardless of which testing framework is underneath.
Try It
- Install Jest, write
math.jsandmath.test.jsabove, and confirm both tests pass withnpx jest --verbose. - Write a test that deliberately fails, run it, and read every part of the failure output, the expected value, the received value, and the line number.
- Add a third test to the same
describeblock, coveringaddwith two negative numbers, and confirm all three tests pass together. - Add the
"test": "jest"script topackage.json, and confirmnpm testruns the same suite.
Recap
- Jest finds and runs
*.test.jsfiles automatically,describegroups tests,it/testdefines one,expect(...).toBe(...)asserts a value. - A failing test shows exactly what was expected, what was received, and where, no manual comparison needed.
npm test, backed by a"test": "jest"script, is the standard way any Node.js project’s test suite gets run.
Next lesson: testing functions with real logic, including the cases where they’re supposed to fail.