Configuring nyc, tape and ts-node
⋅ 1 min readI've been writing a lot of TypeScript in the last few years, and have come to love it for writing my Node.js projects.
My workflow
For tests, I religiously use tape because unlike mocha, it does not need a test-runner — tape tests can be run as regular Node modules. tape also doesn't pollute global with "magic" functions, which mocha does with abandon.
nyc is pretty much the only choice for code coverage in Node-land. It is a CLI-wrapper around instanbuljs and is regularly maintained.
I prefer to use ts-node for tests as it lets me rapidly test without having to run tsc every time to transpile tests to JS.
The problem
One of the biggest pain points in using this combination is correctly configuring them.
Most of the folks that use these same tools run into weird coverage issues (inconsistent results across runs, 0% coverage, runtime errors. etc.)
A Google search lands in istanbuljs/nyc/issues #497, which has conflicting information. Not to mention the officially recommended config preset nyc-config-typescript had an issue that was only just fixed.
The solution
After a lot of trial and error, here's what works best.
-
nycconfig — I'd recommend saving this in.nycrc.jsonin your project's root directory. Saving it as a.jsonfile gives you better syntax highlighting in the editor of your choice.{ "extension": [ ".ts" ], "require": [ "ts-node/register/transpile-only" ], "exclude": [ "**/*.d.ts", "coverage/", "test/" ], "reporter": [ "text", "lcov" ], "cache": false } -
npmscripts —{ "scripts": { "test": "tape -r ts-node/register/transpile-only test/**/*.test.ts test/*.test.ts", "coverage": "nyc tape -r ts-node/register/transpile-only test/**/*.test.ts test/*.test.ts", } }
You can replace ts-node/register/transpile-only with ts-node/register if you run into unexpected issues, but in most cases it works and is ~50% faster in my experience.
Happy testing! 🥳