vitest-test-ratio
v0.2.0
Published
Measure Code to Test LOC ratio in Vitest projects.
Readme
vitest-test-ratio
vitest-test-ratio is a single-purpose CLI that measures Code LOC to Test LOC ratio for Vitest projects, with a Rails stats style summary line.
This repository uses pnpm for development.
Features
- Reads
vitest.config.*when possible and usestest.include/test.exclude - Falls back to built-in test patterns when config cannot be resolved
- Collects
ts/tsx/js/jsxsource and test files - Excludes
.d.ts,node_modules,dist,coverage, and detected test files from code files - Computes project-level Code LOC, Test LOC, ratio, and unmatched file count
- Maps source files to tests by basename (supports
__tests__andtests/) - Supports text output and JSON output
Install
npm install -g vitest-test-ratioOr run without installing globally:
npx vitest-test-ratioWith pnpm:
pnpm dlx vitest-test-ratioUsage
vitest-test-ratio [options]Options
--filesShow per-file ratio entries--top <n>Show top N files by code LOC (implies--files)--jsonOutput JSON--cwd <path>Analyze a specific directory (default: current directory)-h, --helpShow help
Vitest Integration Examples
vitest-test-ratio is a standalone CLI, not a Vitest plugin.
You can still integrate it into a Vitest workflow with npm scripts or CI.
Run after Vitest locally
{
"scripts": {
"test:with-ratio": "vitest run && vitest-test-ratio --files"
}
}Run after tests in GitHub Actions
- name: Test
run: pnpm run test
- name: Test ratio
run: pnpm vitest-test-ratio --jsonText Output
Summary line format:
Code LOC: 4231 Test LOC: 3120 Code to Test Ratio: 1:0.74 Unmatched files: 12Per-file unmatched entries show:
No matching testJSON Output
JSON includes:
project.codeLocproject.testLocproject.ratioproject.ratioFormattedproject.unmatchedFilesfiles[]entries:sourcecodeLoctestLocratioratioFormattedmatchedTests
For unmatched files:
testLoc: 0ratio: nullmatchedTests: []
ratio and ratioFormatted are capped at a maximum of 1:2.00.
How File Matching Works
- Source and test files are matched by basename.
- Example:
src/user.tsmatchestests/user.test.ts,__tests__/user.spec.ts, etc. - If multiple tests match one source file, their LOC values are summed.
LOC Counting Policy
This tool uses sloc by default for supported file types (.ts, .tsx, .js, .jsx) and reads source lines from its result.
If sloc cannot be applied for a file (for example, unsupported extension or runtime parse failure), it falls back to a lightweight local counter:
- remove comment-only content with a simple parser
- count non-empty lines
This fallback keeps the CLI resilient without requiring additional user setup.
Vitest Config Support
vitest-test-ratio looks for:
vitest.config.tsvitest.config.mtsvitest.config.ctsvitest.config.jsvitest.config.mjsvitest.config.cjs
When readable, it extracts test.include and test.exclude string arrays. If extraction fails, built-in test patterns are used.
Non-goals
- No coverage integration
- No import graph analysis
- No Vite config parsing
- No workspace/deep monorepo features
- No extra metrics beyond code/test ratio output
Development
pnpm install
pnpm run lint
pnpm run test
pnpm run test:coverage
pnpm run buildTry It Locally
This repository includes a runnable sample project under examples/basic.
pnpm run demoQuality Gates
- Unit tests: Vitest (
tests/*.test.ts) - Coverage:
pnpm run test:coverage(output:coverage/, HTML report:coverage/index.html) - Lint / format: Biome (
pnpm run lint,pnpm run format) - CI: GitHub Actions (
.github/workflows/ci.yml) runs lint, build, and test
Publish with GitHub Actions
This repository includes a publish workflow:
- publish.yml
- Trigger: push tag
v*or manualworkflow_dispatch - Auth: npm Trusted Publishing (OIDC, no
NPM_TOKENsecret)
Required setup:
- On npm, open package settings and add a Trusted Publisher for this GitHub repository/workflow
- Keep the workflow file path as
.github/workflows/publish.yml - Bump
package.jsonversion - Push a matching tag (example:
v0.1.0for version0.1.0)
Example release commands:
git tag v0.1.0
git push origin v0.1.0License
MIT
