How to increase test coverage in a TypeScript or JavaScript project
How to increase test coverage in a TypeScript or JavaScript project
Most teams know their coverage number is low. The hard part is not knowing, it is finding the time to fix it without grinding a sprint to a halt. Here is the method we use, stripped to what actually moves the number.
Step 1: measure a real baseline
You cannot improve what you have not measured on the actual code. Run your suite with coverage on, not a guess from a dashboard that may be stale.
For Vitest:
vitest run --coverage
For Jest:
jest --coverage
Read the per-file report, not just the headline percentage. The headline hides the truth. A repo at 60 percent overall often has a handful of core files at 10 to 20 percent and a pile of trivial files at 100 percent. The low files are where the risk lives and where the points are.
Step 2: rank uncovered code by risk, not by size
Do not start at the top of the file list. Start where a bug would hurt most:
- Money, auth, and data-writes first. A missed branch here is a real incident.
- Then the code that changes often. High-churn files break the most.
- Leave generated code, config, and thin wrappers for last, or exclude them.
The goal is not a vanity number. It is to lock down the behavior that matters with tests that would actually catch a regression.
Step 3: write tests against real behavior, not to pad the number
The fastest way to make coverage lie is to write tests that execute lines without asserting anything meaningful. They turn the bar green and catch nothing.
A good coverage test does three things: it calls the real function, it asserts on the real output or side effect, and it would fail if someone broke the behavior. If deleting the assertion does not break the test, the test is theater.
For each uncovered function, cover the happy path, the obvious error path, and the one edge case that is easy to get wrong (empty input, null, boundary value, timezone, off-by-one). That trio gets most functions from zero to genuinely covered.
Step 4: keep the existing suite green
Raising coverage is worthless if you break something on the way. Run the full suite after every batch of new tests, not just the new ones. New coverage that turns an old test red is a net loss until you understand why.
What number should you aim for?
Eighty percent line coverage is the practical engineering ceiling for most codebases. The last ten to twenty points are usually defensive branches, generated code, and platform guards that cost three to five times more effort per point and add close to nothing. Chasing 100 percent is how teams burn weeks testing their test infrastructure. We wrote more on the right coverage target if you want the longer argument.
The shortcut
If you want to see where your repo stands in two minutes, run a free coverage check. Paste a public GitHub repo and we clone it, run its suite, and report the real line-coverage number. No setup, no CI integration.
And if the gap is real but the time is not there, we do this as a service. Coverage Uplift takes your JavaScript or TypeScript repo to 80 percent, verified in a sandbox against your own suite, with a full refund if we miss the target. You review and merge the pull request on your own timeline.