DeepFrontend
Practice ArenaBlogSign in
Go Pro
DeepFrontend

Interview-grade learning paths and hands-on practice for mid-to-senior engineers. Master internals, patterns, and system architecture with runnable code.

All systems operational

Core Courses

  • -JavaScript Internals
  • -React Reconciliation
  • -TypeScript rigor
  • -Next.js Caching
  • -Node.js Event Loop
  • -System Design
  • -Web Security
  • -CSS & Page Layouts

Explore

  • Learning Paths
  • Practice Arena
  • Pricing Options
  • HTML Sitemap

Resources

  • Privacy Policy
  • Terms of Service
  • Email Support

© 2026 DeepFrontend. All rights reserved.

Expert learning environments for web engineering teams.

Home/Testing/Unit Testing (Jest & Vitest)
beginner25 min read·Updated Jul 2026Expert reviewed

Unit Testing (Jest & Vitest)

Unit tests verify isolated code modules. By utilizing assertions, setup/teardown hooks, and comparing Jest with the modern ESM-first Vitest, developers build fast, maintainable test suites.

testingunit-testingjestvitestassertionsesm

Knowledge Check

2 questions · pass at 70%

0/2
mediummcq

1. What is the primary architectural difference between Jest and Vitest?


Interview Questions

1 questions

Cheatsheet

Download-ready reference
Cheatsheet
Describe       Groups related tests (e.g. describe("cart module")).
Test/It        Defines a single test case block.
Expect         Executes assertions (toBe, toEqual, toContain).
beforeEach     Setup hook executing before each test case.
beforeAll      Setup hook executing once before the suite.

Basic Assertions:
  expect(x).toBe(y)        Referential equality (===).
  expect(x).toEqual(y)     Deep object/array equality check.
  expect(x).toBeNull()     Asserts x is null.
  expect(x).toThrow()      Asserts function throws an error.

Related topics

Testing Strategy & the Testing PyramidMockingPro

On this page

25m
Knowledge CheckInterview QuestionsCheatsheet

Concept#

Writing Assertions#

A unit test describes a single requirement, executing code and verifying results against expected constraints using assertions:

import { describe, test, expect } from 'vitest';
import { calculateTotal } from './cart';
 
describe('calculateTotal()', () => {
  test('should sum items and apply discount', () => {
    const items = [
      { price: 100, quantity: 2 },
      { price: 50, quantity: 1 }
    ];
    const total = calculateTotal(items, 10); // 10% discount
    
    expect(total).toBe(225); // (200 + 50) - 25
  });
 
  test('should return 0 for empty arrays', () => {
    expect(calculateTotal([], 0)).toBe(0);
  });
});

Hooks: Setup & Teardown#

Hooks execute logic at specific intervals inside the test runner process, useful for resetting databases or clearing timers:

import { beforeEach, afterEach } from 'vitest';
 
beforeEach(() => {
  // Runs once before EACH test block
  initializeTestDatabase();
});
 
afterEach(() => {
  // Runs once after EACH test block
  clearDatabase();
});

Jest vs Vitest: The Shift to ESM#

  • Jest: The historical industry standard. Built on CommonJS, requiring heavy transpilers (like Babel) to support modern ES Modules, causing setup frictions in TypeScript.
  • Vitest: The modern successor. Built natively on Vite, supporting ESM, TypeScript, and JSX out of the box with zero configuration. It reuses your Vite configuration file, making it much faster (powered by esbuild) and easier to integrate.

Common Mistakes#

1. Sharing mutable state variables across test blocks#

Declaring a global let variable and mutating it inside test blocks can result in tests bleeding into each other:

// ❌ WRONG: Modifying shared state
let cart = [];
test('add item', () => { cart.push('item'); ... });
test('should be empty', () => { expect(cart.length).toBe(0); }); // Fails!

Always redeclare states locally inside beforeEach() or helper factory functions.

2. Nesting describe blocks too deeply#

Nesting describe blocks 5+ levels deep makes test output files difficult to read and maintain. Keep suites flat, grouping tests logically by function names.


Best Practices#

  • AAA Pattern: Structure tests clearly: Arrange (set up variables), Act (execute the function), Assert (verify result).
  • Verify edge cases: Do not just test happy paths. Assert how your code behaves with empty inputs, nulls, negative numbers, or invalid formats.
  • Ensure isolation: A single test block should never depend on the execution of a prior test block.