A minimal Typescript setup that demonstrates unit testing in NodeJS and generating coverage. Since there are so many moving parts in the test ecosystem, this is an attempt to isolate them separately and debug them individually
yarn test
- tests with coverage by c8 - coverage reporter in c8-coverage
folderyarn test:nyc
- tests wth coverage by nyc - numbers not accurate, attempted fix - yarn test:nyc:fix
does not work as wellyarn test:watch
- does not work yet - limitation of mocha + ESMyarn test-only
- run tests without coverage
TODO: Diagram to explain how all this fits in together comes here
Specifying module
is the most important - this governs how the output transpiled file will look like
target is useful for any feature replacement
if need be
sourceMap is useful for debbugers
Build time compilation is the invocation of the typescript compiler through an npm script like yarn compile
. The compiled
files are written to the dist
directory (or configured outDir
in tsconfig.json
)
on-the-fly compilation is achieved by require hooks
- ts-node
intercepts every import
request and compiles the imported
module. It internally
uses the same tsconfig.json
file but does not write to dist
- instead it uses a temporary directory and cleans it up soon after the module is loaded
into memory
mocha
mocha
allows for specifying hooks that it passes on to nodejs - we specify the ts-node/esm
hook to facilitate on-the-fly compilation of imports in test files.mocharc.cjs
for full configuration usedCoverage is usually one layer above tests
You can generate coverage in 2 ways -
Coverage is generated by nyc
- for typescript, extend from the @istanbuljs/nyc-config-typescript
[Not working] Coverage numbers are wrong - the @istanbuljs/esm-loader-hook
needs to be used, but I could not figure out
a way to make it work. See issue
Coverage can also be generated via c8 which used nodejs' native coverage support - this is far simpler
to configure - see .c8rc.json
Add something like - "instrument": "nyc instrument src in-src",
to your package.json to instrument
Modify your imports under the test
directory to import from in-src
wherever you import from src
Remove on-the-fly instrumentation (can run tests directly, instead of through nyc - i.e yarn test-only
)
A sampling of errors encountered - goes to show the many pieces of the puzzle here -
"loader": "ts-node/esm"
in .mocharc.cjs@istanbuljs/esm-loader-hook
for nyc to generate the right coverage stats, but
that fails with [ERR_UNKNOWN_FILE_EXTENSION]. It looks like setting this option for nyc disables the "experimental-specifier-resolution": "node"
that we set for mocha (in .mocharc.cjs
). Run test:nyc:fix
to reproduce this