Loading...
Generates a comprehensive test coverage report when the coding session ends
{
"hookConfig": {
"hooks": {
"stop": {
"script": "./.claude/hooks/test-coverage-final-report.sh",
"matchers": [
"*"
]
}
}
},
"scriptContent": "#!/bin/bash\n\necho \"🧪 Test Coverage Final Report - Analyzing test coverage...\"\necho \"⏰ Session ended: $(date)\"\necho \"═══════════════════════════════════════════════════\"\n\n# Detect project type and testing framework\nPROJECT_TYPE=\"unknown\"\nTEST_FRAMEWORK=\"unknown\"\nCOVERAGE_AVAILABLE=false\n\necho \"🔍 Detecting project type and testing framework...\"\n\n# JavaScript/Node.js project detection\nif [ -f \"package.json\" ]; then\n PROJECT_TYPE=\"node\"\n echo \"📦 Node.js project detected\"\n \n # Detect testing framework\n if grep -q '\"jest\"' package.json 2>/dev/null; then\n TEST_FRAMEWORK=\"jest\"\n echo \"🃏 Jest testing framework detected\"\n elif grep -q '\"vitest\"' package.json 2>/dev/null; then\n TEST_FRAMEWORK=\"vitest\"\n echo \"⚡ Vitest testing framework detected\"\n elif grep -q '\"mocha\"' package.json 2>/dev/null; then\n TEST_FRAMEWORK=\"mocha\"\n echo \"☕ Mocha testing framework detected\"\n elif grep -q '\"karma\"' package.json 2>/dev/null; then\n TEST_FRAMEWORK=\"karma\"\n echo \"🔄 Karma testing framework detected\"\n fi\n \n# Python project detection\nelif [ -f \"requirements.txt\" ] || [ -f \"setup.py\" ] || [ -f \"pyproject.toml\" ]; then\n PROJECT_TYPE=\"python\"\n echo \"🐍 Python project detected\"\n \n if command -v pytest >/dev/null 2>&1; then\n TEST_FRAMEWORK=\"pytest\"\n echo \"🧪 Pytest testing framework available\"\n elif python -c \"import unittest\" 2>/dev/null; then\n TEST_FRAMEWORK=\"unittest\"\n echo \"🔬 Unittest framework available\"\n fi\n \n# Rust project detection\nelif [ -f \"Cargo.toml\" ]; then\n PROJECT_TYPE=\"rust\"\n TEST_FRAMEWORK=\"cargo\"\n echo \"🦀 Rust project detected\"\n \n# Go project detection\nelif [ -f \"go.mod\" ]; then\n PROJECT_TYPE=\"go\"\n TEST_FRAMEWORK=\"go_test\"\n echo \"🐹 Go project detected\"\n \n# Java project detection\nelif [ -f \"pom.xml\" ] || [ -f \"build.gradle\" ]; then\n PROJECT_TYPE=\"java\"\n echo \"☕ Java project detected\"\n \n if [ -f \"pom.xml\" ]; then\n TEST_FRAMEWORK=\"maven\"\n echo \"🏗️ Maven build system detected\"\n else\n TEST_FRAMEWORK=\"gradle\"\n echo \"🐘 Gradle build system detected\"\n fi\nfi\n\necho \"\"\necho \"📊 Running coverage analysis for $PROJECT_TYPE project...\"\n\n# Run coverage based on project type\ncase \"$PROJECT_TYPE\" in\n \"node\")\n case \"$TEST_FRAMEWORK\" in\n \"jest\")\n echo \"🃏 Running Jest with coverage...\"\n if npm test -- --coverage --silent 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Jest coverage completed successfully\"\n elif npm run test:coverage 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Coverage script completed successfully\"\n else\n echo \"⚠️ Jest coverage command failed - check test configuration\"\n fi\n ;;\n \"vitest\")\n echo \"⚡ Running Vitest with coverage...\"\n if npx vitest run --coverage 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Vitest coverage completed successfully\"\n else\n echo \"⚠️ Vitest coverage command failed\"\n fi\n ;;\n \"mocha\")\n echo \"☕ Running Mocha with nyc coverage...\"\n if npx nyc mocha 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Mocha coverage completed successfully\"\n else\n echo \"⚠️ Mocha coverage requires nyc - install with: npm install --save-dev nyc\"\n fi\n ;;\n *)\n echo \"⚠️ No recognized testing framework - attempting generic npm test\"\n if npm test 2>/dev/null; then\n echo \"✅ Tests completed (coverage unknown)\"\n else\n echo \"❌ Tests failed or not configured\"\n fi\n ;;\n esac\n ;;\n \"python\")\n case \"$TEST_FRAMEWORK\" in\n \"pytest\")\n echo \"🧪 Running pytest with coverage...\"\n if pytest --cov=. --cov-report=term-missing --cov-report=html 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Pytest coverage completed successfully\"\n else\n echo \"⚠️ Pytest coverage failed - install with: pip install pytest-cov\"\n fi\n ;;\n \"unittest\")\n echo \"🔬 Running unittest with coverage...\"\n if python -m coverage run -m unittest discover 2>/dev/null; then\n python -m coverage report 2>/dev/null\n COVERAGE_AVAILABLE=true\n echo \"✅ Unittest coverage completed successfully\"\n else\n echo \"⚠️ Coverage.py not available - install with: pip install coverage\"\n fi\n ;;\n *)\n echo \"⚠️ No Python testing framework detected\"\n ;;\n esac\n ;;\n \"rust\")\n echo \"🦀 Running Cargo test with coverage...\"\n if command -v cargo-tarpaulin >/dev/null 2>&1; then\n if cargo tarpaulin --out Html 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Cargo tarpaulin coverage completed successfully\"\n else\n echo \"⚠️ Cargo tarpaulin failed\"\n fi\n else\n echo \"⚠️ cargo-tarpaulin not installed - install with: cargo install cargo-tarpaulin\"\n echo \"🔄 Running basic cargo test...\"\n cargo test 2>/dev/null && echo \"✅ Tests completed (coverage unavailable)\"\n fi\n ;;\n \"go\")\n echo \"🐹 Running Go test with coverage...\"\n if go test -coverprofile=coverage.out ./... 2>/dev/null; then\n go tool cover -html=coverage.out -o coverage.html 2>/dev/null\n COVERAGE_AVAILABLE=true\n echo \"✅ Go coverage completed successfully\"\n else\n echo \"⚠️ Go test coverage failed\"\n fi\n ;;\n \"java\")\n case \"$TEST_FRAMEWORK\" in\n \"maven\")\n echo \"🏗️ Running Maven test with JaCoCo coverage...\"\n if mvn test jacoco:report 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Maven JaCoCo coverage completed successfully\"\n else\n echo \"⚠️ Maven coverage failed - ensure JaCoCo plugin is configured\"\n fi\n ;;\n \"gradle\")\n echo \"🐘 Running Gradle test with JaCoCo coverage...\"\n if ./gradlew test jacocoTestReport 2>/dev/null; then\n COVERAGE_AVAILABLE=true\n echo \"✅ Gradle JaCoCo coverage completed successfully\"\n else\n echo \"⚠️ Gradle coverage failed - ensure JaCoCo plugin is configured\"\n fi\n ;;\n esac\n ;;\n *)\n echo \"❓ Unknown project type - cannot generate coverage report\"\n echo \"💡 Supported: Node.js, Python, Rust, Go, Java\"\n ;;\nesac\n\necho \"\"\necho \"📈 Coverage Report Summary:\"\necho \"═══════════════════════════\"\n\n# Display coverage results based on available formats\nif [ \"$COVERAGE_AVAILABLE\" = true ]; then\n case \"$PROJECT_TYPE\" in\n \"node\")\n if [ -d \"coverage\" ]; then\n echo \"📊 Coverage files found in coverage/ directory\"\n \n # Try to parse coverage summary\n if [ -f \"coverage/coverage-summary.json\" ]; then\n echo \"📋 Coverage Summary:\"\n cat coverage/coverage-summary.json 2>/dev/null | jq -r '.total | \"Lines: \" + (.lines.pct|tostring) + \"% (\" + (.lines.covered|tostring) + \"/\" + (.lines.total|tostring) + \")\", \"Branches: \" + (.branches.pct|tostring) + \"% (\" + (.branches.covered|tostring) + \"/\" + (.branches.total|tostring) + \")\", \"Functions: \" + (.functions.pct|tostring) + \"% (\" + (.functions.covered|tostring) + \"/\" + (.functions.total|tostring) + \")\", \"Statements: \" + (.statements.pct|tostring) + \"% (\" + (.statements.covered|tostring) + \"/\" + (.statements.total|tostring) + \")\"' 2>/dev/null || echo \"Coverage summary parsing failed\"\n fi\n \n echo \"🌐 HTML Report: file://$(pwd)/coverage/index.html\"\n fi\n ;;\n \"python\")\n if [ -d \"htmlcov\" ]; then\n echo \"🌐 HTML Report: file://$(pwd)/htmlcov/index.html\"\n fi\n ;;\n \"rust\")\n if [ -f \"tarpaulin-report.html\" ]; then\n echo \"🌐 HTML Report: file://$(pwd)/tarpaulin-report.html\"\n fi\n ;;\n \"go\")\n if [ -f \"coverage.html\" ]; then\n echo \"🌐 HTML Report: file://$(pwd)/coverage.html\"\n fi\n ;;\n \"java\")\n if [ -d \"target/site/jacoco\" ]; then\n echo \"🌐 HTML Report: file://$(pwd)/target/site/jacoco/index.html\"\n elif [ -d \"build/reports/jacoco/test/html\" ]; then\n echo \"🌐 HTML Report: file://$(pwd)/build/reports/jacoco/test/html/index.html\"\n fi\n ;;\n esac\nelse\n echo \"❌ No coverage data available\"\n echo \"💡 Coverage Setup Tips:\"\n case \"$PROJECT_TYPE\" in\n \"node\")\n echo \" • For Jest: Add 'collectCoverage: true' to jest.config.js\"\n echo \" • For Vitest: Add 'coverage' provider to vite.config.js\"\n echo \" • Run: npm install --save-dev @vitest/coverage-c8\"\n ;;\n \"python\")\n echo \" • Install: pip install pytest-cov coverage\"\n echo \" • Run: pytest --cov=your_package\"\n ;;\n \"rust\")\n echo \" • Install: cargo install cargo-tarpaulin\"\n echo \" • Run: cargo tarpaulin --out Html\"\n ;;\n \"go\")\n echo \" • Built-in: go test -coverprofile=coverage.out\"\n echo \" • View: go tool cover -html=coverage.out\"\n ;;\n \"java\")\n echo \" • Add JaCoCo plugin to Maven/Gradle configuration\"\n echo \" • Maven: mvn test jacoco:report\"\n echo \" • Gradle: ./gradlew test jacocoTestReport\"\n ;;\n esac\nfi\n\necho \"\"\necho \"💡 Coverage Best Practices:\"\necho \" • Aim for 80%+ line coverage on critical code\"\necho \" • Focus on testing business logic and edge cases\"\necho \" • Use coverage to identify untested code, not as a quality metric\"\necho \" • Write meaningful tests, not just coverage-driven tests\"\necho \" • Exclude generated code and vendor dependencies\"\necho \" • Set up coverage thresholds in CI/CD pipelines\"\n\necho \"\"\necho \"🎯 Test coverage analysis complete!\"\necho \"═══════════════════════════════════════════════════\"\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"stop": {
"script": "./.claude/hooks/test-coverage-final-report.sh",
"matchers": [
"*"
]
}
}
}#!/bin/bash
echo "🧪 Test Coverage Final Report - Analyzing test coverage..."
echo "⏰ Session ended: $(date)"
echo "═══════════════════════════════════════════════════"
# Detect project type and testing framework
PROJECT_TYPE="unknown"
TEST_FRAMEWORK="unknown"
COVERAGE_AVAILABLE=false
echo "🔍 Detecting project type and testing framework..."
# JavaScript/Node.js project detection
if [ -f "package.json" ]; then
PROJECT_TYPE="node"
echo "📦 Node.js project detected"
# Detect testing framework
if grep -q '"jest"' package.json 2>/dev/null; then
TEST_FRAMEWORK="jest"
echo "🃏 Jest testing framework detected"
elif grep -q '"vitest"' package.json 2>/dev/null; then
TEST_FRAMEWORK="vitest"
echo "⚡ Vitest testing framework detected"
elif grep -q '"mocha"' package.json 2>/dev/null; then
TEST_FRAMEWORK="mocha"
echo "☕ Mocha testing framework detected"
elif grep -q '"karma"' package.json 2>/dev/null; then
TEST_FRAMEWORK="karma"
echo "🔄 Karma testing framework detected"
fi
# Python project detection
elif [ -f "requirements.txt" ] || [ -f "setup.py" ] || [ -f "pyproject.toml" ]; then
PROJECT_TYPE="python"
echo "🐍 Python project detected"
if command -v pytest >/dev/null 2>&1; then
TEST_FRAMEWORK="pytest"
echo "🧪 Pytest testing framework available"
elif python -c "import unittest" 2>/dev/null; then
TEST_FRAMEWORK="unittest"
echo "🔬 Unittest framework available"
fi
# Rust project detection
elif [ -f "Cargo.toml" ]; then
PROJECT_TYPE="rust"
TEST_FRAMEWORK="cargo"
echo "🦀 Rust project detected"
# Go project detection
elif [ -f "go.mod" ]; then
PROJECT_TYPE="go"
TEST_FRAMEWORK="go_test"
echo "🐹 Go project detected"
# Java project detection
elif [ -f "pom.xml" ] || [ -f "build.gradle" ]; then
PROJECT_TYPE="java"
echo "☕ Java project detected"
if [ -f "pom.xml" ]; then
TEST_FRAMEWORK="maven"
echo "🏗️ Maven build system detected"
else
TEST_FRAMEWORK="gradle"
echo "🐘 Gradle build system detected"
fi
fi
echo ""
echo "📊 Running coverage analysis for $PROJECT_TYPE project..."
# Run coverage based on project type
case "$PROJECT_TYPE" in
"node")
case "$TEST_FRAMEWORK" in
"jest")
echo "🃏 Running Jest with coverage..."
if npm test -- --coverage --silent 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Jest coverage completed successfully"
elif npm run test:coverage 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Coverage script completed successfully"
else
echo "⚠️ Jest coverage command failed - check test configuration"
fi
;;
"vitest")
echo "⚡ Running Vitest with coverage..."
if npx vitest run --coverage 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Vitest coverage completed successfully"
else
echo "⚠️ Vitest coverage command failed"
fi
;;
"mocha")
echo "☕ Running Mocha with nyc coverage..."
if npx nyc mocha 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Mocha coverage completed successfully"
else
echo "⚠️ Mocha coverage requires nyc - install with: npm install --save-dev nyc"
fi
;;
*)
echo "⚠️ No recognized testing framework - attempting generic npm test"
if npm test 2>/dev/null; then
echo "✅ Tests completed (coverage unknown)"
else
echo "❌ Tests failed or not configured"
fi
;;
esac
;;
"python")
case "$TEST_FRAMEWORK" in
"pytest")
echo "🧪 Running pytest with coverage..."
if pytest --cov=. --cov-report=term-missing --cov-report=html 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Pytest coverage completed successfully"
else
echo "⚠️ Pytest coverage failed - install with: pip install pytest-cov"
fi
;;
"unittest")
echo "🔬 Running unittest with coverage..."
if python -m coverage run -m unittest discover 2>/dev/null; then
python -m coverage report 2>/dev/null
COVERAGE_AVAILABLE=true
echo "✅ Unittest coverage completed successfully"
else
echo "⚠️ Coverage.py not available - install with: pip install coverage"
fi
;;
*)
echo "⚠️ No Python testing framework detected"
;;
esac
;;
"rust")
echo "🦀 Running Cargo test with coverage..."
if command -v cargo-tarpaulin >/dev/null 2>&1; then
if cargo tarpaulin --out Html 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Cargo tarpaulin coverage completed successfully"
else
echo "⚠️ Cargo tarpaulin failed"
fi
else
echo "⚠️ cargo-tarpaulin not installed - install with: cargo install cargo-tarpaulin"
echo "🔄 Running basic cargo test..."
cargo test 2>/dev/null && echo "✅ Tests completed (coverage unavailable)"
fi
;;
"go")
echo "🐹 Running Go test with coverage..."
if go test -coverprofile=coverage.out ./... 2>/dev/null; then
go tool cover -html=coverage.out -o coverage.html 2>/dev/null
COVERAGE_AVAILABLE=true
echo "✅ Go coverage completed successfully"
else
echo "⚠️ Go test coverage failed"
fi
;;
"java")
case "$TEST_FRAMEWORK" in
"maven")
echo "🏗️ Running Maven test with JaCoCo coverage..."
if mvn test jacoco:report 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Maven JaCoCo coverage completed successfully"
else
echo "⚠️ Maven coverage failed - ensure JaCoCo plugin is configured"
fi
;;
"gradle")
echo "🐘 Running Gradle test with JaCoCo coverage..."
if ./gradlew test jacocoTestReport 2>/dev/null; then
COVERAGE_AVAILABLE=true
echo "✅ Gradle JaCoCo coverage completed successfully"
else
echo "⚠️ Gradle coverage failed - ensure JaCoCo plugin is configured"
fi
;;
esac
;;
*)
echo "❓ Unknown project type - cannot generate coverage report"
echo "💡 Supported: Node.js, Python, Rust, Go, Java"
;;
esac
echo ""
echo "📈 Coverage Report Summary:"
echo "═══════════════════════════"
# Display coverage results based on available formats
if [ "$COVERAGE_AVAILABLE" = true ]; then
case "$PROJECT_TYPE" in
"node")
if [ -d "coverage" ]; then
echo "📊 Coverage files found in coverage/ directory"
# Try to parse coverage summary
if [ -f "coverage/coverage-summary.json" ]; then
echo "📋 Coverage Summary:"
cat coverage/coverage-summary.json 2>/dev/null | jq -r '.total | "Lines: " + (.lines.pct|tostring) + "% (" + (.lines.covered|tostring) + "/" + (.lines.total|tostring) + ")", "Branches: " + (.branches.pct|tostring) + "% (" + (.branches.covered|tostring) + "/" + (.branches.total|tostring) + ")", "Functions: " + (.functions.pct|tostring) + "% (" + (.functions.covered|tostring) + "/" + (.functions.total|tostring) + ")", "Statements: " + (.statements.pct|tostring) + "% (" + (.statements.covered|tostring) + "/" + (.statements.total|tostring) + ")"' 2>/dev/null || echo "Coverage summary parsing failed"
fi
echo "🌐 HTML Report: file://$(pwd)/coverage/index.html"
fi
;;
"python")
if [ -d "htmlcov" ]; then
echo "🌐 HTML Report: file://$(pwd)/htmlcov/index.html"
fi
;;
"rust")
if [ -f "tarpaulin-report.html" ]; then
echo "🌐 HTML Report: file://$(pwd)/tarpaulin-report.html"
fi
;;
"go")
if [ -f "coverage.html" ]; then
echo "🌐 HTML Report: file://$(pwd)/coverage.html"
fi
;;
"java")
if [ -d "target/site/jacoco" ]; then
echo "🌐 HTML Report: file://$(pwd)/target/site/jacoco/index.html"
elif [ -d "build/reports/jacoco/test/html" ]; then
echo "🌐 HTML Report: file://$(pwd)/build/reports/jacoco/test/html/index.html"
fi
;;
esac
else
echo "❌ No coverage data available"
echo "💡 Coverage Setup Tips:"
case "$PROJECT_TYPE" in
"node")
echo " • For Jest: Add 'collectCoverage: true' to jest.config.js"
echo " • For Vitest: Add 'coverage' provider to vite.config.js"
echo " • Run: npm install --save-dev @vitest/coverage-c8"
;;
"python")
echo " • Install: pip install pytest-cov coverage"
echo " • Run: pytest --cov=your_package"
;;
"rust")
echo " • Install: cargo install cargo-tarpaulin"
echo " • Run: cargo tarpaulin --out Html"
;;
"go")
echo " • Built-in: go test -coverprofile=coverage.out"
echo " • View: go tool cover -html=coverage.out"
;;
"java")
echo " • Add JaCoCo plugin to Maven/Gradle configuration"
echo " • Maven: mvn test jacoco:report"
echo " • Gradle: ./gradlew test jacocoTestReport"
;;
esac
fi
echo ""
echo "💡 Coverage Best Practices:"
echo " • Aim for 80%+ line coverage on critical code"
echo " • Focus on testing business logic and edge cases"
echo " • Use coverage to identify untested code, not as a quality metric"
echo " • Write meaningful tests, not just coverage-driven tests"
echo " • Exclude generated code and vendor dependencies"
echo " • Set up coverage thresholds in CI/CD pipelines"
echo ""
echo "🎯 Test coverage analysis complete!"
echo "═══════════════════════════════════════════════════"
exit 0Jest coverage reports zero percent despite passing tests
collectCoverage disabled or wrong paths in jest.config.js. Verify: 'collectCoverage: true, collectCoverageFrom: ["src/**/*.{js,ts}"]'. Or force: 'npm test -- --coverage --collectCoverageFrom="src/**"'.
Coverage summary JSON parsing fails with jq errors
coverage-summary.json missing or malformed. Check exists: '[ -f coverage/coverage-summary.json ]' before jq. Generate: add 'coverageReporters: ["json-summary", "html"]' to jest.config.js.
Python pytest-cov not found despite pytest installation
Separate package required. Install: 'pip install pytest-cov coverage'. Verify: 'pytest --version' shows cov plugin. Or use coverage.py: 'coverage run -m pytest; coverage report'.
Rust tarpaulin installation fails with compilation errors
Requires nightly Rust and specific deps. Use Docker: 'docker run --rm -v $PWD:/volume xd009642/tarpaulin cargo tarpaulin'. Or alternative: 'cargo install cargo-llvm-cov' for stable Rust.
HTML report links show file:// protocol not opening in browser
Terminal doesn't hyperlink file:// URLs. Add open command: 'echo "Open: coverage/index.html"; open coverage/index.html 2>/dev/null || xdg-open coverage/index.html' auto-launching browser.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters