Test coverage
Analyze test coverage and suggest tests for uncovered codeFrom its SKILL.md
npx -y skills add manastalukdar/ai-devstudio --skill test-coverageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
17.4 KB, ~4.5k tokens by cl100k_base, as published. Nobody here has run it
Test Coverage Analysis & Enhancement
I'll analyze your test coverage, identify untested code paths, and suggest comprehensive tests for uncovered areas.
Arguments: $ARGUMENTS - specific paths or coverage focus areas
Phase 1: Coverage Tool Detection
Pre-Flight Checks: Before starting, I'll verify:
- Test framework and coverage tool availability
- Existing test configuration
- Coverage thresholds and requirements
- CI/CD coverage reporting setup
Coverage Tool Detection:
# Auto-detect coverage tooling
detect_coverage_tool() {
if [ -f "package.json" ]; then
# JavaScript/TypeScript ecosystem
if grep -q "jest" package.json; then
echo "jest --coverage"
elif grep -q "vitest" package.json; then
echo "vitest --coverage"
elif grep -q "c8" package.json; then
echo "c8"
elif grep -q "nyc" package.json || grep -q "istanbul" package.json; then
echo "nyc"
fi
elif [ -f "pyproject.toml" ] || [ -f "setup.py" ]; then
# Python ecosystem
if grep -q "pytest-cov" pyproject.toml setup.py requirements.txt 2>/dev/null; then
echo "pytest-cov"
elif command -v coverage >/dev/null 2>&1; then
echo "coverage"
fi
elif [ -f "go.mod" ]; then
# Go has built-in coverage
echo "go test -cover"
elif [ -f "Gemfile" ]; then
# Ruby ecosystem
if grep -q "simplecov" Gemfile; then
echo "simplecov"
fi
elif [ -f "pom.xml" ] || [ -f "build.gradle" ]; then
# Java ecosystem
echo "jacoco"
fi
}
COVERAGE_TOOL=$(detect_coverage_tool)
if [ -z "$COVERAGE_TOOL" ]; then
echo "No coverage tool detected. Suggestions:"
echo " - JavaScript: npm install --save-dev jest (includes coverage)"
echo " - Python: pip install pytest-cov"
echo " - Go: Built-in (go test -cover)"
echo " - Ruby: gem install simplecov"
exit 1
fi
echo "Detected coverage tool: $COVERAGE_TOOL"
Coverage Report Generation: I'll use bash to run coverage and parse reports efficiently:
# Generate coverage report with minimal output formats
case "$COVERAGE_TOOL" in
"jest --coverage")
# Only generate JSON summary (skip HTML report generation)
npm test -- --coverage --coverageReporters=json-summary 2>&1 | tail -20
;;
"pytest-cov")
# Only generate JSON report (skip HTML)
pytest --cov=. --cov-report=json --cov-report=term-missing:skip-covered 2>&1 | tail -20
;;
"go test -cover")
go test -coverprofile=coverage.out ./... 2>&1
go tool cover -func=coverage.out | tail -20
;;
esac
# Parse coverage summary (avoid reading thousands of lines of HTML)
if [ -f "coverage/coverage-summary.json" ]; then
# Jest/NYC format - extract just total metrics
jq -c '.total' coverage/coverage-summary.json
elif [ -f "coverage.json" ]; then
# pytest-cov format - extract just summary
jq -c '.totals' coverage.json
fi
This gets coverage metrics without reading thousands of lines of HTML reports, saving 90%+ tokens.
Phase 2: Coverage Metrics Analysis
I'll analyze multiple coverage dimensions:
-
Line Coverage
- Percentage of lines executed
- Identifies completely untested files
-
Branch Coverage
- Percentage of if/else, switch paths tested
- More meaningful than line coverage
-
Function Coverage
- Percentage of functions called
- Identifies unused code
-
Statement Coverage
- More granular than line coverage
- Multiple statements per line counted separately
Coverage Report Parsing:
# Extract low-coverage files for targeted analysis
parse_low_coverage_files() {
if [ -f "coverage/coverage-summary.json" ]; then
# Extract files with <80% coverage
jq -r 'to_entries[] |
select(.value.lines.pct < 80) |
"\(.key): \(.value.lines.pct)% lines, \(.value.branches.pct)% branches"' \
coverage/coverage-summary.json
fi
}
LOW_COVERAGE_FILES=$(parse_low_coverage_files)
Coverage Threshold Checking:
# Check if project has coverage requirements
check_coverage_thresholds() {
# Jest configuration
if [ -f "jest.config.js" ] || [ -f "jest.config.json" ]; then
grep -A 10 "coverageThreshold" jest.config.* 2>/dev/null
fi
# pytest configuration
if [ -f "pyproject.toml" ]; then
grep -A 5 "fail_under" pyproject.toml 2>/dev/null
fi
# Go coverage threshold (custom)
if [ -f ".coverage-threshold" ]; then
cat .coverage-threshold
fi
}
THRESHOLDS=$(check_coverage_thresholds)
Phase 3: Uncovered Code Identification
Strategic File Analysis:
I'll focus on files with coverage gaps using Grep before full Read:
# Find uncovered functions in low-coverage files (JavaScript/TypeScript)
Grep pattern="^(export )?(async )?function \w+"
glob="$LOW_COVERAGE_FILE_PATTERN"
output_mode="content"
head_limit=15
-n=true
# Find uncovered classes in low-coverage files (Python)
Grep pattern="^class \w+"
glob="$LOW_COVERAGE_FILE_PATTERN"
output_mode="content"
head_limit=15
-n=true
# Find error handling that might be uncovered
Grep pattern="throw new|raise |catch \(|except "
glob="$LOW_COVERAGE_FILE_PATTERN"
output_mode="content"
head_limit=10
Uncovered Code Patterns I'll Identify:
-
Error Handling Paths
try { await operation(); } catch (error) { // UNCOVERED: Error path not tested logger.error(error); throw new CustomError(error); } -
Edge Cases in Conditionals
if (value > 100) { return 'high'; } else if (value > 50) { return 'medium'; } else { return 'low'; // UNCOVERED: Never tested } -
Validation Logic
def validate_input(data): if not data: raise ValueError("Data required") # UNCOVERED if not isinstance(data, dict): raise TypeError("Dict required") # UNCOVERED return True -
Async Error Paths
async function fetchData(url) { if (!url) { throw new Error('URL required'); // UNCOVERED } const response = await fetch(url); if (!response.ok) { throw new Error('Fetch failed'); // UNCOVERED } return response.json(); } -
Default/Fallback Cases
switch (action.type) { case 'CREATE': return handleCreate(action); case 'UPDATE': return handleUpdate(action); default: return state; // UNCOVERED: Default case not tested }
Phase 4: Missing Test Identification
I'll identify critical gaps:
-
Untested Public APIs
# Find exported functions EXPORTED_FUNCTIONS=$(Grep pattern="^export (async )?function (\w+)" glob="src/**/*.{js,ts}" output_mode="content" head_limit=20) # Check which ones lack tests (bash comparison) echo "$EXPORTED_FUNCTIONS" | while read -r line; do FUNC_NAME=$(echo "$line" | grep -oP "function \K\w+") # Quick Grep check in test files HAS_TEST=$(Grep pattern="$FUNC_NAME" glob="**/*.{test,spec}.*" output_mode="files_with_matches" head_limit=1) [ -z "$HAS_TEST" ] && echo "UNTESTED: $FUNC_NAME" done -
Untested Error Scenarios
# Find error throwing code in low-coverage files Grep pattern="throw new|raise |throw Error" glob="$LOW_COVERAGE_FILE_PATTERN" output_mode="content" head_limit=15 -n=true -
Untested Edge Cases
- Empty array/object handling
- Null/undefined checks
- Boundary values (0, -1, MAX_INT)
- Invalid input types
-
Integration Points
- API endpoints
- Database operations
- External service calls
- File system operations
Phase 5: Test Suggestions & Generation
For each uncovered area, I'll suggest tests:
Example: Uncovered Error Path
// Uncovered code in src/user-service.js:
async function createUser(data) {
if (!data.email) {
throw new Error('Email required'); // UNCOVERED
}
return db.users.create(data);
}
// Suggested test:
describe('UserService.createUser', () => {
it('should throw error when email is missing', async () => {
await expect(createUser({ name: 'Test' }))
.rejects.toThrow('Email required');
});
it('should throw error when email is null', async () => {
await expect(createUser({ email: null, name: 'Test' }))
.rejects.toThrow('Email required');
});
it('should throw error when email is empty string', async () => {
await expect(createUser({ email: '', name: 'Test' }))
.rejects.toThrow('Email required');
});
});
Example: Uncovered Branch
# Uncovered code in src/calculator.py:
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero") # UNCOVERED
return a / b
# Suggested test:
def test_divide_by_zero():
"""Test division by zero raises ValueError"""
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(10, 0)
def test_divide_by_negative():
"""Test division by negative number"""
assert divide(10, -2) == -5.0
def test_divide_floats():
"""Test division with floating point precision"""
assert abs(divide(1, 3) - 0.333333) < 0.00001
Example: Uncovered Edge Case
// Uncovered code in src/array-utils.js:
function getFirst(arr) {
return arr[0]; // What if arr is empty? UNCOVERED
}
// Suggested tests:
describe('getFirst', () => {
it('should return first element of array', () => {
expect(getFirst([1, 2, 3])).toBe(1);
});
it('should return undefined for empty array', () => {
expect(getFirst([])).toBeUndefined();
});
it('should handle single-element array', () => {
expect(getFirst([42])).toBe(42);
});
it('should return first element even if falsy', () => {
expect(getFirst([0, 1, 2])).toBe(0);
expect(getFirst([null, 1, 2])).toBeNull();
});
});
Phase 6: Coverage Improvement Strategy
Prioritization Framework:
I'll prioritize test additions based on:
-
Risk Level (Critical → Low)
- Critical: Security, data integrity, financial logic
- High: Core business logic, user-facing features
- Medium: Utility functions, helpers
- Low: Logging, formatting, trivial getters
-
Impact (High → Low)
- High: Code used frequently, critical paths
- Medium: Occasional use, important features
- Low: Rarely used, edge features
-
Effort (Low → High)
- Low: Simple unit tests, pure functions
- Medium: Mocked integration tests
- High: Complex integration/E2E tests
Coverage Improvement Plan:
COVERAGE IMPROVEMENT STRATEGY
==============================
Phase 1: Critical Uncovered Code (Priority: High Risk + High Impact)
├── auth/login.js:45-52 - Error handling in authentication
├── payment/process.js:78-85 - Failed payment scenarios
└── user/validate.js:23-30 - Input validation edge cases
Phase 2: Important Features (Priority: High Impact + Low Effort)
├── api/users.js:120-135 - User creation edge cases
├── utils/format.js:45-60 - Edge cases in formatting
└── services/email.js:89-95 - Email send failure handling
Phase 3: Code Quality (Priority: Medium Impact + Low Effort)
├── helpers/string.js:12-25 - String utility edge cases
├── models/user.js:67-72 - Model validation
└── config/parser.js:34-40 - Config parsing errors
Phase 4: Comprehensive Coverage (Priority: Low Risk + Low Effort)
├── utils/constants.js - Getter coverage
├── types/validators.js - Type checking edge cases
└── formatters/date.js - Date formatting edge cases
Phase 7: Test Generation & Implementation
I'll generate and add tests:
-
Create git checkpoint
git add -A git commit -m "Pre test-coverage-improvement checkpoint" || echo "No changes" -
Generate tests for uncovered code:
- Write comprehensive test cases
- Cover all branches and edge cases
- Include descriptive test names
- Add comments explaining edge cases
-
Verify coverage improvement:
# Run tests with coverage npm test -- --coverage # Compare before/after coverage echo "Coverage improved from X% to Y%" -
Validate test quality:
- Tests actually assert behavior
- No false positives (tests that pass without testing)
- Good test organization and naming
- Proper setup/teardown
Integration with Existing Skills
Workflow Integration:
- After
/testruns → Check coverage with/test-coverage - After
/scaffold→ Ensure new code has tests - Before
/commit→ Verify coverage thresholds met - During
/review→ Include coverage analysis - With
/test-async→ Cover async edge cases - With
/test-antipatterns→ Quality + coverage together
Skill Suggestions:
- Low coverage in complex async →
/test-async - Coverage but poor quality →
/test-antipatterns - New feature needs tests →
/tdd-red-green - Complex uncovered logic →
/explain-like-senior
Reporting
I'll provide comprehensive coverage analysis:
TEST COVERAGE ANALYSIS REPORT
==============================
CURRENT COVERAGE:
├── Lines: 78.5% (target: 80%)
├── Branches: 65.2% (target: 75%)
├── Functions: 82.1% (target: 85%)
└── Statements: 77.8% (target: 80%)
FILES BELOW THRESHOLD:
├── src/auth/login.js: 45.2% (critical!)
├── src/payment/process.js: 52.8% (critical!)
├── src/api/users.js: 71.3%
├── src/utils/validate.js: 68.9%
└── src/helpers/format.js: 74.5%
UNCOVERED CRITICAL CODE:
├── Error handling paths: 23 instances
├── Edge case branches: 18 instances
├── Validation logic: 12 instances
└── Async error paths: 8 instances
TESTS SUGGESTED:
├── Authentication error scenarios: 8 tests
├── Payment failure handling: 6 tests
├── Input validation edge cases: 12 tests
├── API error responses: 10 tests
└── Utility function edge cases: 15 tests
AFTER IMPROVEMENTS:
├── Lines: 78.5% → 87.3% (+8.8%)
├── Branches: 65.2% → 81.7% (+16.5%)
├── Functions: 82.1% → 91.2% (+9.1%)
└── Statements: 77.8% → 86.9% (+9.1%)
TESTS ADDED: 51 new tests
FILES MODIFIED: 12 test files
EXECUTION TIME: +2.3s (acceptable)
NEXT STEPS:
├── Run tests to verify all pass
├── Review generated tests for quality
├── Update CI/CD coverage thresholds
└── Document testing coverage requirements
Coverage Tools Configuration
I can help set up coverage tools:
Jest (JavaScript/TypeScript):
{
"jest": {
"collectCoverage": true,
"coverageDirectory": "coverage",
"coverageReporters": ["text", "lcov", "json-summary"],
"coverageThreshold": {
"global": {
"lines": 80,
"branches": 75,
"functions": 85,
"statements": 80
}
},
"collectCoverageFrom": [
"src/**/*.{js,ts}",
"!src/**/*.d.ts",
"!src/**/*.test.{js,ts}"
]
}
}
pytest-cov (Python):
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=term-missing --cov-report=html --cov-fail-under=80"
[tool.coverage.run]
omit = ["*/tests/*", "*/test_*.py"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise NotImplementedError"
]
Safety Guarantees
What I'll NEVER do:
- Generate tests that don't actually test
- Lower coverage thresholds to "pass"
- Test implementation details instead of behavior
- Add AI attribution to commits or code
- Create tests that give false confidence
What I WILL do:
- Generate meaningful, behavior-focused tests
- Cover edge cases and error paths
- Improve actual code quality, not just metrics
- Maintain test maintainability
- Create clear commit messages (no AI attribution)
Credits
This skill is based on:
- Istanbul/nyc - JavaScript coverage tool standards
- Jest - Built-in coverage capabilities
- pytest-cov - Python coverage testing
- JaCoCo - Java code coverage library
- SimpleCov - Ruby coverage analysis
- Testing Best Practices - Community-driven coverage guidelines
Token Optimization
Expected range: 1,200–2,000 tokens (initial), 200 tokens (coverage good)
Caching: Caches coverage tool detection in .claude/cache/test-coverage/tool.json for 7 days. Invalidated when package.json changes.
Early exit: Returns immediately if all coverage thresholds are already met.
Patterns used: Grep-before-Read, early exit, Bash for system queries, caching
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.