Documentation
Migrate from Codecov
Keep generating coverage in CI. Put tested.dev on the PR. Require the job. Then Codecov comes out.
1. What you already have
- Node 24+.
- Tests that write coverage. Vitest/Jest default is Istanbul/V8
coverage/coverage-final.json. The CLI also reads lcov, Cobertura, JaCoCo, gcov text, and SimpleCov. Setcoverage.pathif it isn't the default file.
Keep the test step. Full path: Install. CI: GitHub Action.
2. Install
pnpm add -D @tested/cli
tested setup
# writes .tested.yaml
# runs doctor (Node 24+, git, config, coverage path, origin)Local tested diff / tested check need no account, no token. Same for the Action with push default false.
3. Thresholds
Floors live in .tested.yaml. The Action has no threshold inputs. Fields: Config.
# .tested.yaml
base: origin/main
testRunner: pnpm test -- --coverage
thresholds:
patch: 80 # new executable lines
project: 60 # overall floor
paths:
- glob: src/api/**
patch: 90
project: 90
- glob: src/cli/**
patch: 70
project: 70Optional thresholds.paths: independent floors per glob. Omitted patch / project inherit the global floors. A glob with no files this run is skipped (not 0%). Not flags. tested check fails when any matched path is under its floor. Coverage stays the only PR gate.
If codecov.yml has flags, put them here. tested check and tested push grade each package from this run.
flags:
frontend:
paths: ["apps/web/**", "packages/ui/**"]
thresholds:
patch: 90
backend:
paths: ["apps/api/**"]A job already scoped to one package: Action flag: frontend.
4. GitHub Action
Gate: no account, no token. Pin uses: to a SHA in production. Same snippet as GitHub Action.
# .github/workflows/tested.yml
name: tested
on:
pull_request:
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm test -- --coverage
- uses: tested-hq/cli/action@main # pin uses: to a SHA in production
with:
version: 0.1.10Share / push: install tested-dev-app, mint TESTED_TOKEN. The project page is /repos/{owner}/{name} — 30-day mainline coverage and the PRs. push: true on the PR. mainline: true on default branch. Inputs on GitHub Action.
- uses: tested-hq/cli/action@main # pin uses: to a SHA in production
with:
version: 0.1.10
push: 'true'
pr-number: ${{ github.event.pull_request.number }}
token: ${{ secrets.TESTED_TOKEN }}If CI writes more than one coverage file, list them in coverage.path or Action files. The CLI merges them and checks once.
5. Require, then remove Codecov
Require the job
Open a PR so
coverageruns once. Repo Settings → Branches → require status checks → addcoverage.
Delete Codecov
- Codecov Action step
codecov.ymlCODECOV_TOKEN- Required
codecov/*checks - Codecov badge. Last: the tested.dev badge.
[](https://app.tested.dev/repos/{owner}/{name})Done when tested doctor is clean and that job is the required check.
6. Verify
tested doctor
# No FAIL. WARN is fine if you know why.The coverage job posts a conclusion. With push: true, the log has a share URL. If it fails: Troubleshooting.