RepoFold

Unit Tests

This page documents the unit test suite for Express core modules. The tests validate routing, middleware, request/response extensions, configuration, and error handling. They are the primary mechanism for ensuring correctness during development and before merging changes.

Test Organization

The unit tests reside in the test directory at the repository root. Each test file corresponds to a specific module or feature of the Express library. The test suite contains 77 test files covering:

  • Routing: route matching, parameters, route separation, error routing
  • Middleware: execution order, error-handling middleware, middleware stacking
  • Request/Response: HTTP method helpers, header manipulation, content negotiation, response formatting
  • Configuration: application settings, view engine configuration, trust proxy
  • Error handling: synchronous and asynchronous error propagation, error response formatting
  • Edge cases: boundary conditions, malformed input, security-relevant scenarios

Each test file is independent and focuses on a single module or feature. Tests use a testing framework (likely Mocha) and supertest for HTTP assertions, as is standard in the Express ecosystem.

Testing Framework

The test suite uses the Mocha testing framework with supertest for HTTP-level assertions. The package.json scripts define the test runner commands:

ScriptCommandPurpose
test(defined in package.json)Run the full test suite
test-ci(defined in package.json)Run tests in CI mode (with coverage)
test-cov(defined in package.json)Run tests with code coverage
test-tap(defined in package.json)Run tests with TAP output

The CI workflows use npm run test-ci for test execution .github/workflows/ci.yml:59-59.

Running Unit Tests

Prerequisites

  • Node.js version 18 or higher (as specified in package.json engines field)
  • npm (or compatible package manager)

Setup

# Install dependencies (including dev dependencies)
npm install

Run Tests

# Run the full test suite
npm test

# Run tests with CI-style output (used in CI workflows)
npm run test-ci

# Run tests with code coverage
npm run test-cov

# Run tests with TAP output format
npm run test-tap

Running Tests on Specific Node Versions

The CI matrix tests against Node.js versions 18 through 26 on both Ubuntu and Windows .github/workflows/ci.yml:33-34. For local development, you can test against your current Node.js version using any of the above commands.

Code Coverage

When running npm run test-ci or npm run test-cov, the test runner generates coverage data in ./coverage/lcov.info. In CI, these coverage reports are:

  1. Uploaded as artifacts per matrix combination .github/workflows/ci.yml:62-67
  2. Merged using lcov into a single report .github/workflows/ci.yml:82-85
  3. Uploaded to Coveralls for visibility .github/workflows/ci.yml:87-90

Linting

Before running tests, contributors should run the linter to ensure code style consistency:

# Run linting
npm run lint

# Auto-fix linting issues
npm run lint:fix

The lint job in CI runs on ubuntu-latest with the latest LTS Node.js version .github/workflows/ci.yml:14-27.

CI Workflow Integration

The repository has four CI workflows that interact with the unit tests:

WorkflowTriggerTest Execution
ciPush to master/develop/4.x/5.x/5.0, pull requestsFull test matrix (Node 18-26, Ubuntu + Windows)
legacySame branches as ciLegacy Node.js versions (16, 17)
CodeQLPush to master, pull requests to master, weekly scheduleSecurity analysis (no unit tests)
ScorecardBranch protection rules, weekly schedule, push to masterSupply-chain security analysis (no unit tests)

The ci workflow is the primary test pipeline. It runs linting first, then executes the test matrix with npm run test-ci .github/workflows/ci.yml:59-59. The legacy workflow runs the same test command but only on Node.js 16 and 17 .github/workflows/legacy.yml:33-34.

Both workflows use fail-fast: false to ensure all matrix combinations run even if some fail .github/workflows/ci.yml:31-31.

Test Coverage Areas

The unit tests cover the following Express core modules and features:

Application Layer

  • Application creation and configuration
  • Setting and getting application settings
  • Mounting middleware and routes
  • Error handling configuration

Routing

  • Route definition (GET, POST, PUT, DELETE, etc.)
  • Route parameters and pattern matching
  • Route middleware execution order
  • Route separation and modular routing
  • Error routing (error-handling middleware with four arguments)

Middleware

  • Middleware stacking and execution order
  • Error-handling middleware (signature: (err, req, res, next))
  • Middleware that terminates the request-response cycle
  • Middleware that calls next() to pass control

Request Object

  • HTTP method helpers (req.get(), req.accepts(), etc.)
  • Header parsing and content negotiation
  • URL and query string parsing
  • Request body parsing (via body-parser integration)

Response Object

  • Response methods (res.send(), res.json(), res.render(), etc.)
  • Header setting and content type negotiation
  • Status code setting
  • Response formatting (JSON, HTML, plain text)
  • ETag and caching headers

Configuration

  • View engine configuration
  • Template engine integration
  • Trust proxy settings
  • Case-sensitive routing
  • Strict routing

Error Handling

  • Synchronous error propagation
  • Asynchronous error handling (via next(err))
  • Default error response formatting
  • Custom error-handling middleware

Contributor Conventions

When contributing to Express, follow these testing conventions:

  1. Write tests for new features: Every new feature or bug fix should include corresponding unit tests in the test directory.
  2. Maintain test independence: Each test file should be self-contained and not depend on state from other tests.
  3. Use descriptive test names: Test descriptions should clearly indicate what behavior is being verified.
  4. Cover edge cases: Include tests for boundary conditions, error states, and security-relevant scenarios.
  5. Run linting first: Always run npm run lint before submitting changes to ensure code style compliance.
  6. Verify all tests pass: Run npm test locally before pushing changes.
  7. Respect the CI matrix: Tests must pass on all supported Node.js versions and operating systems.
Generated from commit ae6dd37