| name | coverage-readme-workflow-skill |
| description | Ensure test coverage percentage is displayed in README.md for Next.js and Python projects following industry standards |
| license | Apache-2.0 |
| compatibility | opencode |
| metadata | {"audience":"developers","workflow":"test-coverage-documentation","protocol":"autoresearch-opt-in"} |
What I do
I implement a complete test coverage documentation workflow that ensures coverage percentages are displayed in README.md files:
- Detect Project Type: Identify whether the project is Next.js (JavaScript/TypeScript) or Python
- Run Tests with Coverage: Execute test suite with coverage collection for the detected framework
- Parse Coverage Output: Extract coverage percentage from test output (lines, statements, branches, functions)
- Generate Coverage Badge: Create or update coverage badge in industry-standard format (Shields.io badge)
- Update README.md: Add or update coverage badge and percentage display in README.md following industry best practices
- Handle Edge Cases: Deal with missing coverage configuration, zero coverage, or coverage threshold violations
When to use me
Use this workflow when:
- You're creating a new Next.js application or Python project
- You've just added tests to an existing project
- You want to ensure test coverage is visible in project documentation
- You're following industry standard practices for displaying code quality metrics
- You need to update coverage percentage after adding new features
- You're preparing for a code review or PR submission
- You want to track coverage trends over time
Integration: This skill is typically used alongside:
test-generator-framework: After generating tests
nextjs-unit-test-creator: After generating Next.js tests
python-pytest-creator: After generating Python tests
nextjs-pr-workflow: Before creating a PR
pr-creation-workflow: Before creating a PR
Prerequisites
- Next.js project with
package.json OR Python project with pyproject.toml/requirements.txt
- Test framework installed (Jest/Vitest for Next.js, pytest for Python)
- Coverage tools available (built-in to Jest/Vitest, pytest-cov for pytest)
- README.md file exists in project root
- Write permissions to update README.md
- Tests must pass before coverage display
Note: If coverage tools are not installed, this skill will guide you through installation.
Steps
Step 1: Detect Project Type
Determine project type by checking configuration files:
if [ -f "package.json" ]; then
if grep -q '"next"' package.json; then
PROJECT_TYPE="nextjs"
else
PROJECT_TYPE="nodejs"
fi
fi
if [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
PROJECT_TYPE="python"
fi
echo "Detected project type: $PROJECT_TYPE"
Project Types:
nextjs: Next.js application (React framework)
nodejs: JavaScript/TypeScript project without Next.js
python: Python project
Step 2: Detect Test Framework and Coverage Tool
Next.js Projects:
if grep -q '"vitest"' package.json; then
TEST_FRAMEWORK="vitest"
COVERAGE_CMD="npm run test -- --coverage"
elif grep -q '"jest"' package.json; then
TEST_FRAMEWORK="jest"
COVERAGE_CMD="npm run test -- --coverage"
else
if grep -q '"test:coverage"' package.json; then
COVERAGE_CMD="npm run test:coverage"
else
echo "⚠️ No coverage command found in package.json"
echo "Please add coverage script to package.json"
fi
fi
Python Projects:
if grep -q '"pytest-cov"' pyproject.toml 2>/dev/null || grep -q "pytest-cov" requirements.txt 2>/dev/null; then
TEST_FRAMEWORK="pytest"
COVERAGE_CMD="poetry run pytest --cov=. --cov-report=term 2>/dev/null || pytest --cov=. --cov-report=term"
else
echo "⚠️ pytest-cov not installed"
echo "Install with: pip install pytest-cov"
echo "Or with Poetry: poetry add --group dev pytest-cov"
fi
Step 3: Run Tests with Coverage
Next.js (Jest/Vitest):
echo "Running coverage for Next.js project..."
$COVERAGE_CMD 2>&1 | tee /tmp/coverage_output.txt
COVERAGE_PERCENT=$(grep -oP '\d+(?=%)' /tmp/coverage_output.txt | head -1)
LINES_COV=$(grep -oP 'Lines\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
STATEMENTS_COV=$(grep -oP 'Statements\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
BRANCHES_COV=$(grep -oP 'Branches\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
FUNCTIONS_COV=$(grep -oP 'Functions\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
echo "Coverage Results:"
echo " Total: ${COVERAGE_PERCENT}%"
echo " Lines: ${LINES_COV}%"
echo " Statements: ${STATEMENTS_COV}%"
echo " Branches: ${BRANCHES_COV}%"
echo " Functions: ${FUNCTIONS_COV}%"
Python (pytest-cov):
echo "Running coverage for Python project..."
$COVERAGE_CMD 2>&1 | tee /tmp/coverage_output.txt
COVERAGE_PERCENT=$(grep -oP '\d+(?=%)' /tmp/coverage_output.txt | head -1)
LINES_COV=$(grep -oP 'Lines\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
BRANCHES_COV=$(grep -oP 'Branches\s*:\s*\K\d+(?=%)' /tmp/coverage_output.txt | head -1)
echo "Coverage Results:"
echo " Total: ${COVERAGE_PERCENT}%"
echo " Lines: ${LINES_COV}%"
echo " Branches: ${BRANCHES_COV}%"
Step 4: Generate Coverage Badge
Create coverage badge in industry-standard Shields.io format:
BADGE_URL="https://img.shields.io/badge/coverage-${COVERAGE_PERCENT}%25-${BADGE_COLOR}.svg"
if [ "${COVERAGE_PERCENT}" -ge 80 ]; then
BADGE_COLOR="brightgreen"
elif [ "${COVERAGE_PERCENT}" -ge 60 ]; then
BADGE_COLOR="yellow"
elif [ "${COVERAGE_PERCENT}" -ge 40 ]; then
BADGE_COLOR="orange"
else
BADGE_COLOR="red"
fi
COVERAGE_BADGE=""
echo "Coverage badge: ${COVERAGE_BADGE}"
Badge Color Scheme (Industry Standard):
- brightgreen (>= 80%): Excellent coverage
- yellow (60-79%): Good coverage, room for improvement
- orange (40-59%): Moderate coverage, needs attention
- red (< 40%): Poor coverage, requires immediate action
Step 5: Update README.md
Check for Existing Coverage Badge:
if grep -q "coverage" README.md; then
EXISTING_COVERAGE=true
echo "Found existing coverage badge in README.md"
else
EXISTING_COVERAGE=false
echo "No existing coverage badge found"
fi
Update README.md Based on Project Type:
For Next.js Projects:
if [ "$EXISTING_COVERAGE" = "true" ]; then
sed -i "s|!\[Coverage\](.*)|${COVERAGE_BADGE}|" README.md
else
if grep -q "^\[!\[" README.md; then
sed -i "/^\[!\[.*\](.*)\]/a ${COVERAGE_BADGE}" README.md
else
sed -i "1,/^# /s|^# \(.*\)|# \1\n\n${COVERAGE_BADGE}|" README.md
fi
fi
For Python Projects:
if [ "$EXISTING_COVERAGE" = "true" ]; then
sed -i "s|!\[Coverage\](.*)|${COVERAGE_BADGE}|" README.md
else
if grep -q "^\[!\[" README.md; then
sed -i "/^\[!\[.*\](.*)\]/a ${COVERAGE_BADGE}" README.md
else
sed -i "1,/^# /s|^# \(.*\)|# \1\n\n${COVERAGE_BADGE}|" README.md
fi
fi
Add Coverage Section (If Not Exists):
if ! grep -q "## Test Coverage" README.md; then
cat >> README.md <<EOF
## Test Coverage
[]
| Metric | Coverage |
|--------|----------|
| Lines | ${LINES_COV}% |
| Statements | ${STATEMENTS_COV}% |
| Branches | ${BRANCHES_COV}% |
| Functions | ${FUNCTIONS_COV}% |
**Total Coverage:** ${COVERAGE_PERCENT}%
To run tests with coverage:
\`\`\`bash
${COVERAGE_CMD}
\`\`\`
EOF
fi
Step 6: Verify README.md Update
echo "✅ README.md updated successfully!"
echo ""
echo "Coverage badge added:"
grep -o '\[!\[Coverage\].*svg\)' README.md
echo ""
echo "To view README.md:"
echo " cat README.md"
echo ""
echo "To commit changes:"
echo " git add README.md"
echo " git commit -m 'docs: update coverage badge to ${COVERAGE_PERCENT}%'"
Step 7: Display Summary
echo "==================================================================="
echo "Coverage Documentation Complete!"
echo "==================================================================="
echo ""
echo "Project Type: $PROJECT_TYPE"
echo "Test Framework: $TEST_FRAMEWORK"
echo ""
echo "Coverage Results:"
echo " Overall: ${COVERAGE_PERCENT}%"
echo " Lines: ${LINES_COV}%"
if [ -n "${STATEMENTS_COV}" ]; then
echo " Statements: ${STATEMENTS_COV}%"
fi
if [ -n "${BRANCHES_COV}" ]; then
echo " Branches: ${BRANCHES_COV}%"
fi
if [ -n "${FUNCTIONS_COV}" ]; then
echo " Functions: ${FUNCTIONS_COV}%"
fi
echo ""
echo "Badge Color: ${BADGE_COLOR}"
echo "Badge URL: ${BADGE_URL}"
echo ""
echo "README.md has been updated with coverage badge."
echo "==================================================================="
Coverage Badge Templates
Basic Badge (Minimal):

Comprehensive Badge Section:
## Badges
[](https://github.com/username/repo/actions/workflows/test.yml)
[](https://github.com/username/repo/actions/workflows/test.yml)
Detailed Coverage Table:
## Test Coverage
| Metric | Coverage | Badge |
|--------|----------|--------|
| Overall | 85% |  |
| Lines | 87% |  |
| Branches | 82% |  |
| Functions | 88% |  |
**To run tests with coverage:**
```bash
npm run test -- --coverage
## Coverage Thresholds (Industry Standards)
| Coverage Range | Quality Level | Badge Color | Action Required |
|----------------|--------------|-------------|----------------|
| 90-100% | Excellent | brightgreen | Maintain |
| 80-89% | Good | brightgreen | Monitor |
| 70-79% | Acceptable | yellow | Improve |
| 60-69% | Fair | orange | Improve |
| 0-59% | Poor | red | Improve immediately |
## Best Practices
- **Minimum Coverage**: Aim for at least 80% coverage for production code
- **Badge Placement**: Place coverage badge prominently at the top of README.md
- **Automatic Updates**: Set up CI/CD pipeline to update badge automatically
- **Multiple Metrics**: Display overall coverage and breakdown (lines, branches, functions)
- **Trend Tracking**: Consider showing coverage trends over time
- **Threshold Enforcement**: Configure coverage thresholds in test configuration
- **False Positives**: Exclude test files and non-critical code from coverage
- **Documentation**: Explain how to run tests with coverage in README.md
## Next.js-Specific Best Practices
### Jest Configuration:
```javascript
// jest.config.js
module.exports = {
collectCoverageFrom: [
'components/**/*.{js,jsx,ts,tsx}',
'app/**/*.{js,jsx,ts,tsx}',
'lib/**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
'!**/.next/**',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
}
Vitest Configuration:
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'.next/',
'**/*.d.ts',
'**/*.config.*',
],
threshold: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
},
},
},
})
Python-Specific Best Practices
Pytest Configuration:
[run]
omit =
tests/*
*/tests/*
*/__init__.py
*/migrations/*
venv/*
.venv/*
[report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if __name__ == .__main__.:
if TYPE_CHECKING:
Pytest Configuration with Thresholds:
[pytest]
addopts = --cov=. --cov-report=term-missing --cov-fail-under=80
[tool.pytest.ini_options]
addopts = "--cov=. --cov-report=term-missing --cov-fail-under=80"
[tool.coverage.run]
omit = [
"tests/*",
"*/tests/*",
"*/__init__.py",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
]
Common Issues
Coverage Not Detected
Issue: Coverage percentage not extracted from test output
Solution:
npm run test -- --coverage
pytest --cov=. --cov-report=term
Badge Not Updating
Issue: README.md badge shows old coverage percentage
Solution:
sed -i '/!\[Coverage\]/d' README.md
Coverage Command Not Found
Issue: npm run test -- --coverage fails
Solution:
For Next.js with Jest:
jq '.scripts["test:coverage"] = "jest --coverage"' package.json > tmp.json && mv tmp.json package.json
jq '.scripts.test += " --coverage"' package.json > tmp.json && mv tmp.json package.json
For Next.js with Vitest:
{
"scripts": {
"test:coverage": "vitest --coverage"
}
}
For Python with pytest:
pip install pytest-cov
poetry add --group dev pytest-cov
README.md Not Found
Issue: README.md file doesn't exist
Solution:
cat > README.md << 'EOF'
Brief description of the project.
EOF
Coverage Too Low
Issue: Coverage badge shows red color (below 40%)
Solution:
- Identify uncovered code:
npm run test -- --coverage --coverageReporters=json
- Review coverage report in
coverage/coverage-final.json
- Add tests for uncovered code
- Re-run coverage workflow
- Commit updated README.md with improved badge
Coverage Exclusions Not Working
Issue: Test files or non-critical code included in coverage
Solution:
For Jest/Vitest:
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/*.test.{js,jsx,ts,tsx}',
'!src/**/*.spec.{js,jsx,ts,tsx}',
'!src/types/**',
]
For pytest:
[run]
omit =
tests/*
*/tests/*
test_*.py
*_test.py
Troubleshooting Checklist
Before running coverage workflow:
After running coverage workflow:
Iteration Protocol (opt-in)
DO NOT execute any of the following unless AUTORESEARCH_PROTOCOL=1 is set in your environment. When unset, this skill behaves exactly as documented in all sections above; the Iteration Protocol block is descriptive only.
When AUTORESEARCH_PROTOCOL=1:
- Gate check: confirm env var is set; if unset, follow default behavior above.
- Auto-detection: if this skill is invoked on a task that looks iterative (multiple cycles expected), prompt ONCE per session: "This looks iterative. Enable autoresearch protocol? (y/n)". On "y", continue; on "n", default behavior. Cache the answer for the session.
- 5-stage loop: cycle Understand → Hypothesize → Experiment → Evaluate → Log & Iterate. See
autoresearch-core-skill/SKILL.md.
- Evaluator contract: emit
{"pass":bool,"score":N} JSON from a mechanical evaluator. Pass determines keep/revert; score logged to coverage-results.tsv. See autoresearch-core-skill/references/evaluator-contract.md.
- Stuck detection: 3 consecutive non-improving iterations → strategy pivot; 5 consecutive → paradigm shift. See
autoresearch-core-skill/references/stuck-detection.md.
- Audit trail: append every iteration to
coverage-results.tsv (8-column: iteration, commit, metric, delta, status, description, timestamp, evaluator_output). See autoresearch-core-skill/references/audit-trail.md.
- Crash recovery: syntax errors → fix immediately (don't count); runtime → max 3 fix attempts then skip; timeout → revert + log; OOM → smaller variant. See
autoresearch-core-skill/references/crash-recovery.md.
- Git-as-memory: commit before each verify; auto-revert (
git reset --hard HEAD~1) on pass:false.
- Iteration safety: bounded-by-default (
Iterations: 25); safety blocks .env, node_modules/, rm -rf, git push --force. See autoresearch-core-skill/references/iteration-safety.md.
Skill-specific override
Full iteration loop. Converts the one-shot coverage display into an iterative loop targeting a coverage percentage goal. Metric = coverage %; direction = maximize; target = user-specified (default 80%). Emits coverage-results.tsv. Pass = coverage ≥ target.
Max iterations
- Default: 25 iterations
- Hard cap: 100 (explicit
Iterations: unlimited overrides)