Open-Source Wikis

/

Node.js

/

How to contribute

/

Testing

nodejs/node

Testing

The Node.js test suite is large and is split by purpose. Knowing which directory to put a test in (and which directory contains the failing test you are trying to reproduce) saves a lot of time.

Test categories

Directory Purpose
test/parallel/ Default. Independent tests that can run in parallel. Most new tests go here.
test/sequential/ Tests that need exclusive access to ports, FS, or environment.
test/pummel/ Slow / soak tests. Not run on every PR.
test/known_issues/ Failing tests that document known regressions; allowed to fail.
test/abort/ Tests using process.abort() and crash-only paths.
test/async-hooks/ async_hooks integration tests.
test/cctest/ C++ unit tests built into a cctest binary. Run via make cctest.
test/embedding/ Embedder API tests.
test/es-module/ ESM-loader-specific tests.
test/module-hooks/ node --import / customization-hook tests.
test/sea/ Single-Executable Application tests.
test/sqlite/ node:sqlite tests.
test/test-runner/ Tests for node --test (lib/test.js).
test/wasi/ WASI tests.
test/wpt/ Web Platform Tests imported from upstream WPT.
test/fuzzers/ libFuzzer-style harnesses.
test/fixtures/ Shared assets used by the suite. Never run directly.
test/common/ The shared test helpers (require('../common')).
test/internet/ Tests that require network access; skipped in default CI.
test/addons/ Native addon tests (uses node-gyp).
test/js-native-api/ Node-API conformance tests (the JS-side N-API).
test/node-api/ Stable Node-API tests.
test/report/ Tests for process.report / --report-* flags.
test/system-ca/ System trust store integration.
test/client-proxy/ NODE_USE_ENV_PROXY and explicit proxy configuration.
test/pseudo-tty/ Tests run under a fake TTY (uses tools/pseudo-tty.py).
test/tick-processor/ --prof ticks tests.
test/v8-updates/ Tests around V8 imports.
test/doctool/ The tools/doc/ doctool.
test/benchmark/ Benchmarks that should at least run in CI.

The test runner is tools/test.py, a fork of V8's testpy. make test runs the default tiers; CI orchestrates broader matrices.

Common helpers (test/common/)

require('../common') is the entry point. The most-used helpers:

Helper What it does
common.mustCall(fn[, n]) Wraps fn and fails the test if it is not called n times.
common.mustNotCall(msg) Returns a callback that fails if invoked.
common.expectsError(spec) Asserts a thrown error matches code/message/name.
common.platformTimeout(ms) Adjusts timeouts for slow platforms.
common.hasCrypto Skip if Node was built --without-ssl.
common.hasIntl Skip if Node was built without ICU.
common.isWindows/isMacOS Platform branching.
common.PORT Common base port (auto-allocated).

There is also test/common/index.mjs for ESM tests, plus topic-specific subhelpers (test/common/wpt.js, test/common/inspector-helper.js, etc.).

Running tests

# Whole suite
make test

# CI configuration
make test-ci

# Specific tier
python3 tools/test.py parallel sequential

# One file, with verbose output
python3 tools/test.py -J -v test/parallel/test-fs-readfile.js

# Only against the debug build
python3 tools/test.py --mode=debug test/parallel/test-async-wrap-*.js

# Re-run flaky tests
python3 tools/test.py --repeat=10 test/parallel/test-foo.js

The runner accepts file paths or directory tiers. -J runs in parallel; --repeat is invaluable when chasing flaky tests.

Web Platform Tests

test/wpt/ mirrors selected WPT directories from web-platform-tests/wpt. The runner is test/common/wpt.js. To re-import upstream changes, run:

python3 tools/test.py wpt
node test/wpt/test-<area>.js

The .github/workflows/update-wpt.yml workflow drives the periodic pull.

C++ tests

make cctest compiles test/cctest/*.cc into the cctest binary and runs it. Add new tests to node.gyp's test_cctest_sources list. The harness is googletest (deps/googletest/).

Coverage

make coverage          # Linux gcc-based coverage build

The coverage workflows (.github/workflows/coverage-linux*.yml, coverage-windows.yml) upload reports to Codecov; codecov.yml configures thresholds. The .nycrc file is used by node --test --experimental-test-coverage for the test runner's own coverage.

Lint configuration

  • JS: eslint.config.mjs plus partial configs in lib/eslint.config_partial.mjs, test/eslint.config_partial.mjs, doc/eslint.config_partial.mjs. Custom rules live in tools/eslint-rules/ (notably prefer-primordials, crypto-check).
  • Markdown: tools/lint-md/ (a custom remark-lint setup).
  • C++: .cpplint, tools/cpplint.py. Run make lint-cpp.
  • Shell: tools/lint-sh.mjs.
  • Python: pyproject.toml configures Ruff.

make lint covers all of them. Run it before pushing.

CI tiers

The Jenkins CI under https://ci.nodejs.org/ runs platform matrices that GitHub Actions cannot. Collaborators trigger it via @nodejs-github-bot run CI or the request-ci label. The relevant workflows are .github/workflows/auto-start-ci.yml and the daily .github/workflows/daily.yml / daily-wpt-fyi.yml.

Writing a new test

  1. Pick the directory (parallel/ is the default).
  2. Name the file test-<subsystem>-<short>.js.
  3. Start with 'use strict';\nconst common = require('../common');.
  4. Use common.mustCall and common.mustNotCall instead of bare assertions on whether a callback fired.
  5. Keep tests independent; use common.PORT for sockets, tmpdir.refresh() (from test/common/tmpdir.js) for FS.
  6. If the test depends on internals, use --expose-internals (set automatically by helpers under test/common/).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Testing – Node.js wiki | Factory