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: errorRun it:
hereby runtests --tests=tests/cases/compiler/myTest.ts
# or by stem
hereby runtests --tests=myTestOutputs land under tests/baselines/local/:
myTest.js— emitted JavaScriptmyTest.d.ts(if--declaration)myTest.errors.txt— formatted error outputmyTest.types— per-expression typesmyTest.symbols— per-identifier symbol resolutionsmyTest.js.map(if requested)
Review them, then promote to expected baselines:
hereby baseline-acceptThis 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 byselectRange/verify-edit assertions.// @Filename: foo.tsintroduces 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 # synonymFor 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/localOr 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 --coverageOutputs 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.