Testing in TypeScript: A Complete Guide to Frameworks and Tools

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Testing in TypeScript: Frameworks and Tools for Quality Development



TypeScript is a powerful language that adds static typing to JavaScript. However, even strict types do not guarantee the absence of logical errors. To ensure code reliability, testing is necessary. In this article, we will cover the key tools and frameworks for testing TypeScript applications: from unit tests to end-to-end (E2E) testing.



Why Test TypeScript Code?

The TypeScript compiler catches type errors but does not check business logic. Tests help to:

  • Detect regressions during refactoring
  • Document the expected behavior of functions
  • Speed up code reviews through automatic verification
  • Increase confidence in the application's operation


Main Testing Categories

  • Unit Tests — checking individual functions, classes, or modules.
  • Integration Tests — interaction between modules (e.g., with a database).
  • E2E Tests — simulating user actions in a browser.


1. Jest — A Universal Framework for Unit Tests

Jest from Facebook is the most popular choice for TypeScript. It works out of the box: requires no complex configuration, has a built-in mock engine and code coverage report.



Installation:

npm install --save-dev jest @types/jest ts-jest

Add to jest.config.ts:

export default {  preset: 'ts-jest',  testEnvironment: 'node',};


Example of a unit test for a function:

// math.tsexport const add = (a: number, b: number): number => a + b;

// math.test.tsimport { add } from './math';

describe('add', () => { it('should return sum of two numbers', () => { expect(add(2, 3)).toBe(5); });

it('should handle negative numbers', () => { expect(add(-1, -2)).toBe(-3); });});


Mocks in Jest:

// api.tsexport const fetchData = async (id: string) => {  const response = await fetch(`/api/${id}`);  return response.json();};

// api.test.tsjest.mock('./api', () => ({ fetchData: jest.fn().mockResolvedValue({ id: '1', name: 'Test' }),}));

import { fetchData } from './api';

test('should return mocked data', async () => { const data = await fetchData('1'); expect(data.name).toBe('Test');});


2. Mocha + Chai — A Flexible Alternative

Mocha is a test runner that gives you full control over the process. Chai adds expressive assertions.



Installation:

npm install --save-dev mocha chai @types/mocha @types/chai ts-node


Example of an integration test with asynchrony:

// database.tsexport class Database {  async getUser(id: number): Promise<{ id: number; name: string }> {    // emulate request    return { id, name: 'Alice' };  }}

// database.test.tsimport { expect } from 'chai';import { Database } from './database';

describe('Database', () => { it('should return user by id', async () => { const db = new Database(); const user = await db.getUser(1); expect(user).to.have.property('name', 'Alice'); });});


To run, use the command mocha --require ts-node/register src/**/*.test.ts.



3. Cypress — E2E Testing for Web Applications

Cypress is ideal for testing frontend applications in TypeScript. It runs in a real browser and has a convenient GUI interface.



Installation:

npm install --save-dev cypress @cypress/types


Example of an E2E test for a login page

Recommendations