Open-Source Wikis

/

TypeScript

/

How to contribute

/

Testing

microsoft/TypeScript

Testing

The TypeScript test suite is largely a baseline test suite: each test compiles inputs, captures the outputs (.js, .d.ts, errors, types, symbols, source maps), and diffs them against stored expected outputs. New behaviour shows up as baseline changes, which the reviewer must approve.

Runners

Runner Inputs What it checks
compiler tests/cases/compiler/*.ts Compiler output for one-file tests
conformance tests/cases/conformance/**/*.ts Spec-organised compiler tests
fourslash tests/cases/fourslash/*.ts Language-service queries
project tests/cases/project/* Multi-file, single-config tests
projects tests/cases/projects/* Larger multi-project / project-references tests
transpile tests/cases/transpile/*.ts transpileModule output
unittests src/testRunner/unittests/** Direct mocha tests for utilities

Compiler tests

Drop a .ts file into tests/cases/compiler/. Use // @<name>: <value> directives at the top to set compiler options, and // @Filename: to introduce additional virtual files:

// @Filename: main.ts
import { x } from './util';

// @strict: true
// @target: ES2020
// @Filename: util.ts
export const x: number = 1;

const y: string = x; // expected: error

Run it:

hereby runtests --tests=tests/cases/compiler/myTest.ts
# or by stem
hereby runtests --tests=myTest

Outputs land under tests/baselines/local/:

  • myTest.js — emitted JavaScript
  • myTest.d.ts (if --declaration)
  • myTest.errors.txt — formatted error output
  • myTest.types — per-expression types
  • myTest.symbols — per-identifier symbol resolutions
  • myTest.js.map (if requested)

Review them, then promote to expected baselines:

hereby baseline-accept

This copies tests/baselines/local/ to tests/baselines/reference/. Commit both the test source and the new baselines.

Conformance tests

Same syntax as compiler tests, but lives under tests/cases/conformance/<area>/<sub-area>/. The directory structure mirrors the language area: classes/, decorators/, controlFlow/, jsx/, moduleResolution/, node/, etc. Choose the right directory; reviewers will redirect you if it's wrong.

Fourslash tests

Language-service tests use a small DSL. Drop a .ts file into tests/cases/fourslash/:

/// <reference path="fourslash.ts" />

////function foo(/*1*/x: number) {
////    return /*2*/x + 1;
////}

goTo.marker('1');
verify.quickInfoIs('(parameter) x: number');

goTo.marker('2');
verify.completions({ includes: ['x', 'foo'] });

Conventions:

  • //// lines define source code.
  • /*name*/ and /**/ are markers for cursor positions.
  • [|range|] defines a text range used by selectRange / verify-edit assertions.
  • // @Filename: foo.ts introduces a virtual file (without //// prefix on subsequent lines).

The full assertion API lives in src/harness/fourslashImpl.ts (the runtime) and src/harness/fourslashInterfaceImpl.ts (the script-side interface). Common verbs: goTo.*, verify.*, edit.*, format.*, navigateTo.*.

Prefer focused verify.* assertions over wholesale baseline captures — they're easier to read in PRs.

Project tests

tests/cases/project/ hosts multi-file scenarios with a tsconfig.json per test. The runner walks the directory, builds the project, and captures emit + diagnostics. Use these when the bug only reproduces with realistic project configuration (project references, complex paths, etc.).

Running subsets

hereby runtests --runner=fourslash
hereby runtests --runner=compiler
hereby runtests --tests=^autoImport.*$       # pattern
hereby runtests --tests=foo --inspect        # mocha --inspect
hereby runtests --tests=foo -i               # synonym

For parallel runs, use hereby runtests-parallel. The parallel runner shards tests across workers; expect 10–15 minutes for the full suite on a recent laptop.

Inspecting baselines

Manual diff:

git diff --no-index tests/baselines/reference tests/baselines/local

Or set the DIFF env var and run hereby diff to use your favourite GUI diff tool (Beyond Compare, WinMerge, kdiff3, etc.).

Don't write Mocha unit tests

The maintainers' guidance: don't add ad-hoc unit tests under src/testRunner/unittests/. Instead, write a baseline test that exercises the same code path via the public compiler/language-service API. Unit tests have repeatedly drifted from real-world behaviour.

Coverage

hereby runtests --coverage

Outputs LCov + monocart reports under coverage/. The .c8rc.json at the repo root configures it.

Known-bad / flaky

The failed-tests cache lives in scripts/failed-tests.cjs and is consumed by the runner to retry intermittent failures. If a test starts flaking, surface it on the issue tracker rather than silently skipping it.

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

Testing – TypeScript wiki | Factory