How to publish the test coverage report in your React application
You run jest --coverage, get a nice HTML report in coverage/, and then it dies on your machine. This post turns that report into a page anyone can open — useful for an open-source project where contributors want to see how well things are tested, or just to show your work. The stack is minimal:
A perfect "alternative" to SonarQube for small projects.
Publishing a test report is not something everyone does, and some consider it imprudent because you can leak internal detail. The honest use case is an open-source repo where the report helps people contribute, or a teaching post. If you want it gated, a path protected by user and password is enough.
PD: this example is a Next.js app, but it works for any web app that uses jest.
1. Path for the report
First, point the jest coverageDirectory at a public folder:
collectCoverageFrom matters more than people think: without it, coverage is computed only over files a test happened to import, which flatters your numbers. Point it at the real source globs so untested files count as 0, not as absent.
2. Script to modify the report
The report references its CSS/JS/images with relative paths that break once it is served from a sub-path. This script rewrites those paths and customises a couple of texts:
If you prefer a class, use a Jest CustomReporter and implement
onRunComplete.
3. Generate the report on build
Add a postbuild step so the report lands in the public folder every time you build:
4. Create a redirect on the host
So a clean URL serves the folder's index.html:
One thing I got wrong: keep it out of Google
Here is the part no tutorial warns you about, and it bit this very site. Once the coverage report was public, Google indexed every one of those generated HTML pages — dozens of near-identical, text-thin files. That is textbook low value content, and it dilutes the ranking signals of your real pages; it was part of what got this domain flagged by AdSense. Publishing the report is fine, but tell search engines to ignore it:
- Inject
<meta name="robots" content="noindex">into the generated HTML (the same reporter script that fixes the paths can add it), or - Serve an
X-Robots-Tag: noindexheader for the report path or subdomain.
A coverage report is for humans who go looking for it, not for search results. Ship it, then hide it from crawlers.
Here is an example of what the report of this blog looks like: coverage.xabierlameiro.com
