Writing Your First Test
It's time to write your first test! In this lesson, we'll create a simple function and test it step by step. By the end, you'll understand the basic anatomy of a Jest test.
The Function to Test
Let's start with a simple function. Create a file called math.js:
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
function divide(a, b) {
if (b === 0) {
throw new Error('Cannot divide by zero');
}
return a / b;
}
module.exports = { add, subtract, multiply, divide };
Now let's test it!
Your First Test File
Create a test file called math.test.js:
// math.test.js
const { add, subtract, multiply, divide } = require('./math');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
Let's break this down:
require('./math')- Import the function we want to testtest('description', () => {})- Define a test case with a descriptionexpect(add(1, 2))- Call the function and wrap result in expect.toBe(3)- Assert that the result equals 3
Running the Test
Run your test with:
npm test
You should see output like:
PASS ./math.test.js
✓ adds 1 + 2 to equal 3 (2 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Congratulations! You've written and passed your first test!
Adding More Tests
Let's add tests for the other functions:
// math.test.js
const { add, subtract, multiply, divide } = require('./math');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
test('adds negative numbers', () => {
expect(add(-1, -2)).toBe(-3);
});
test('subtracts 5 - 3 to equal 2', () => {
expect(subtract(5, 3)).toBe(2);
});
test('multiplies 3 * 4 to equal 12', () => {
expect(multiply(3, 4)).toBe(12);
});
test('divides 10 / 2 to equal 5', () => {
expect(divide(10, 2)).toBe(5);
});
test('throws error when dividing by zero', () => {
expect(() => divide(10, 0)).toThrow('Cannot divide by zero');
});
Understanding Test Output
When tests pass:
PASS ./math.test.js
✓ adds 1 + 2 to equal 3 (1 ms)
✓ adds negative numbers
✓ subtracts 5 - 3 to equal 2
✓ multiplies 3 * 4 to equal 12
✓ divides 10 / 2 to equal 5
✓ throws error when dividing by zero (1 ms)
When a test fails, Jest shows you exactly what went wrong:
FAIL ./math.test.js
✕ adds 1 + 2 to equal 3 (3 ms)
● adds 1 + 2 to equal 3
expect(received).toBe(expected)
Expected: 3
Received: 4
3 | test('adds 1 + 2 to equal 3', () => {
> 4 | expect(add(1, 2)).toBe(3);
| ^
5 | });
The error message tells you:
- Which test failed
- What value was expected
- What value was received
- The exact line of code that failed
The it Function
You'll often see it used instead of test. They're exactly the same:
// These are equivalent
test('adds numbers', () => {
expect(add(1, 2)).toBe(3);
});
it('adds numbers', () => {
expect(add(1, 2)).toBe(3);
});
Many developers prefer it because it reads more naturally:
it('should add two positive numbers', () => {
expect(add(1, 2)).toBe(3);
});
it('should handle negative numbers', () => {
expect(add(-1, -2)).toBe(-3);
});
Try It Yourself
Here's a function to test. Can you write tests for it?
// greet.js
function greet(name) {
if (!name) {
return 'Hello, stranger!';
}
return `Hello, ${name}!`;
}
module.exports = { greet };
Write tests that verify:
- It greets a named person correctly
- It handles empty/null/undefined names
- It handles names with spaces
Common Mistakes to Avoid
1. Testing Implementation, Not Behavior
// Bad: Testing internal implementation
test('uses the correct formula', () => {
expect(add.toString()).toContain('a + b');
});
// Good: Testing behavior
test('adds numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});
2. Testing Too Much in One Test
// Bad: Multiple assertions testing different things
test('math functions work', () => {
expect(add(1, 2)).toBe(3);
expect(subtract(5, 3)).toBe(2);
expect(multiply(2, 3)).toBe(6);
});
// Good: One concept per test
test('adds numbers', () => {
expect(add(1, 2)).toBe(3);
});
test('subtracts numbers', () => {
expect(subtract(5, 3)).toBe(2);
});
3. Non-Descriptive Test Names
// Bad: Unclear what's being tested
test('test1', () => {
expect(add(1, 2)).toBe(3);
});
// Good: Clear, descriptive name
test('adds two positive integers', () => {
expect(add(1, 2)).toBe(3);
});
Key Takeaways
- Tests are written in files ending with
.test.jsor.spec.js - Use
test()orit()to define test cases - Use
expect()and matchers like.toBe()to make assertions - Run tests with
npm test - Write clear, descriptive test names
- Test behavior, not implementation
- Keep tests focused on one thing
In the next lesson, we'll learn about organizing tests with describe blocks and explore more matchers!

