Lessons · TypeScript · a typed test
A typed test is checked before it runs
A test file is compiled like any other file, so a test that calls the code with the wrong shape fails at compile time, and a test that runs asserts one fact.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
The commonest broken test is a fixture of the wrong shape. TypeScript refuses it before the runner starts, which leaves the runner to find real failures.
How to think about it
One fact per test, named as a sentence. Type the fixtures the way the code is typed. If a call does not compile inside the test, the test just found its first bug.
Worked example
function check(ok: boolean, msg: string): void { if (!ok) throw new Error(msg); }function mean(xs: number[]): number | null { return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null; }The code under test: null for nothing.function test(name: string, fn: () => void): void { fn(); console.log(name, 'passed'); }What a runner does.test('mean of two', () => check(mean([1, 3]) === 2, 'expected 2'));One fact.test('empty list has no mean', () => check(mean([]) === null, 'expected null'));The case the type names. mean of two passed / empty list has no mean passedYour turn
Write the test for one item.
test('one item is its own mean', () => check(mean([7]) === , 'expected 7'));Solve one with the compiler running
The trap
Writing mean('abc') in a test and expecting it to run. It does not compile, and that is the compiler doing the first half of the test's job.