Jest vs pytest — A Beginner-Friendly Getting Started Guide

Writing your first tests can feel like learning a new mini-language on top of the one you already know. Jest (for JavaScript and Node.js) and pytest (for Python) are the two most popular testing frameworks in their respective ecosystems, and they are both designed to get you writing useful tests within minutes. This guide walks through installing each, comparing their syntax side by side, and writing your first real test.

Installing and Setting Up

Jest

npm install --save-dev jest

# package.json
{
  "scripts": {
    "test": "jest"
  }
}

# run it
npm test

pytest

pip install pytest

# no config file required for basic use
# run it
pytest

Both frameworks auto-discover test files by naming convention: Jest looks for files ending in .test.js or .spec.js (or anything inside a __tests__ folder), while pytest looks for files named test_*.py or *_test.py. Neither requires you to register tests manually.

Syntax Side by Side

Jest groups tests using describe and it (or test), and checks results with expect. Pytest uses plain functions prefixed with test_ and Python's built-in assert keyword — no special assertion library required.

// Jest
describe('add', () => {
  it('adds two positive numbers', () => {
    expect(add(2, 3)).toBe(5);
  });
});

# pytest
def test_add_two_positive_numbers():
    assert add(2, 3) == 5

Notice pytest needs no import for assertions — plain assert works because pytest rewrites it internally to give readable failure output. Jest's expect is a global provided by the test runner, so no import is needed there either.

A Worked Example: Testing the Same Function in Both

Say you have a function that checks whether a discount code is valid — it must be uppercase, at least 4 characters, and start with the letter "D".

// discount.js
function isValidDiscountCode(code) {
  if (typeof code !== 'string') return false;
  return code.length >= 4 && code === code.toUpperCase() && code.startsWith('D');
}

module.exports = { isValidDiscountCode };
# discount.py
def is_valid_discount_code(code):
    if not isinstance(code, str):
        return False
    return len(code) >= 4 and code == code.upper() and code.startswith("D")

Jest test file (discount.test.js):

const { isValidDiscountCode } = require('./discount');

describe('isValidDiscountCode', () => {
  it('accepts a valid code', () => {
    expect(isValidDiscountCode('DSAVE10')).toBe(true);
  });

  it('rejects a code that is too short', () => {
    expect(isValidDiscountCode('D10')).toBe(false);
  });

  it('rejects a lowercase code', () => {
    expect(isValidDiscountCode('dsave10')).toBe(false);
  });

  it('rejects a non-string input', () => {
    expect(isValidDiscountCode(null)).toBe(false);
  });
});

Pytest test file (test_discount.py):

from discount import is_valid_discount_code

def test_accepts_a_valid_code():
    assert is_valid_discount_code("DSAVE10") is True

def test_rejects_a_code_that_is_too_short():
    assert is_valid_discount_code("D10") is False

def test_rejects_a_lowercase_code():
    assert is_valid_discount_code("dsave10") is False

def test_rejects_a_non_string_input():
    assert is_valid_discount_code(None) is False

Common Assertion Patterns

Jest has a large family of matchers chained off expect(). Pytest relies on plain Python expressions inside assert, so there is nothing extra to learn beyond the language itself.

// Jest
expect(value).toBe(5);              // strict equality
expect(value).toEqual({ a: 1 });    // deep equality for objects/arrays
expect(value).toBeNull();
expect(array).toContain('apple');
expect(fn).toThrow('invalid input');
expect(value).toBeGreaterThan(10);

# pytest
assert value == 5
assert value == {"a": 1}            # dicts compare deeply by default
assert value is None
assert "apple" in array
with pytest.raises(ValueError, match="invalid input"):
    fn()
assert value > 10

Mocking Basics

Both frameworks let you replace a real dependency (like a database call or an API request) with a fake version so your test stays fast and predictable.

// Jest — mocking a module function
jest.mock('./emailClient');
const { sendEmail } = require('./emailClient');

test('calls sendEmail once on signup', () => {
  sendEmail.mockReturnValue(true);
  signUpUser({ email: 'dev@example.com' });
  expect(sendEmail).toHaveBeenCalledTimes(1);
});
# pytest — mocking with unittest.mock
from unittest.mock import patch

def test_calls_send_email_once_on_signup():
    with patch("email_client.send_email") as mock_send:
        mock_send.return_value = True
        sign_up_user({"email": "dev@example.com"})
        mock_send.assert_called_once()

Jest's mocking is built in — no extra install needed. Pytest uses unittest.mock from the standard library, or the popular pytest-mock plugin, which wraps the same functionality in a mocker fixture for slightly less boilerplate.

Why Starting from a Test Scaffold Saves Time

The hardest part of testing is rarely the assertions — it is remembering the boilerplate: the right import syntax, the describe/test block structure, how to set up a mock, how to test an async function or an expected error. Starting from a correct scaffold for your function signature means you spend your time writing meaningful test cases instead of re-deriving syntax you last used weeks ago.

Frequently Asked Questions

Is Jest or pytest better for beginners?

Neither is objectively better — it depends on your language. Use Jest for JavaScript or TypeScript code, and pytest for Python code. Both have simple, beginner-friendly syntax.

Do I need to install anything extra to mock functions?

No. Jest includes mocking built in via jest.fn() and jest.mock(). Pytest uses unittest.mock from the standard library, or the optional pytest-mock plugin for a fixture-based syntax.

Is there a free tool to generate Jest or pytest test scaffolds?

Yes. The Dev Brains AI Unit Test Generator lets you paste a function signature and get a ready-to-run Jest or pytest test scaffold instantly.

Try the Free Unit Test Generator

Paste a function signature and get a ready-to-run Jest or pytest test scaffold instantly. No signup, no cost.

Related articles