Having test files is necessary but not sufficient — a test suite that only renders components without crashing and ignores business logic in src/lib/ provides false confidence. ISO 25010:2011 §6.5.5 requires that reliability verification covers the critical paths. A payment calculation function, a permission check, or a data transformation that is never tested will eventually receive a change that breaks it; without a coverage gate, no one learns about it until a user reports a wrong order total or a privilege escalation.
Medium because low unit coverage means business logic changes ship without regression verification, turning every refactor into an undetected risk for production correctness.
Prioritize business logic over UI rendering — pure functions in src/lib/, src/utils/, and src/services/ are the highest-return coverage targets. Enforce a minimum in your test config:
// vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
coverage: {
provider: 'v8',
thresholds: {
lines: 60,
functions: 60,
branches: 50,
},
exclude: ['**/*.config.*', 'src/app/**', 'src/components/**'],
},
},
})
Run npx vitest run --coverage to see your current baseline before writing new tests.
ID: code-quality-essentials.testing.unit-coverage
Severity: medium
What to look for: Estimate coverage by comparing the number of test files to source files containing business logic. Focus on src/lib/, src/utils/, src/services/, src/hooks/, and similar directories — not UI component files or page files, which are harder to unit test and often better covered by integration tests. Look for coverage configuration in jest.config.* or vitest.config.* — presence of coverageThreshold (Jest) or thresholds (Vitest) means the project enforces minimum coverage. Check CI workflows for a coverage step. A project with many test files but only testing trivial components (renders without crashing) while leaving core data transformation logic untested still fails this check.
Pass criteria: At least 60% of business logic modules (lib, utils, services, hooks) have corresponding tests with substantive assertions. Coverage tooling is configured or the project clearly covers the majority of critical paths.
Fail criteria: Few or scattered tests; core business logic files have no corresponding tests; test-to-source ratio below 30% for non-trivial codebases.
Skip (N/A) when: No test files exist (covered by the previous check).
Detail on fail: "Estimated coverage below 60%; core logic in src/lib/ appears untested; only UI smoke tests found" (adjust message to what you found)
Remediation: Prioritize testing business logic over UI rendering. Focus on pure functions first — they're easiest to test and carry the most risk when broken:
// vitest.config.ts — enforce coverage minimums
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
coverage: {
provider: 'v8',
thresholds: {
lines: 60,
functions: 60,
branches: 50,
},
exclude: ['**/*.config.*', 'src/app/**', 'src/components/**'],
},
},
})
Run npx vitest run --coverage to see your current baseline before writing tests.