coverage-enhancer
Coverage Enhancer
Line coverage is a floor, not a goal. 100% lines with 50% branches means half your if conditions never ran the other way. This skill targets the uncovered decisions, not just uncovered lines.
Coverage levels — weakest to strongest
| Metric | What it measures | Gaps it misses |
|---|---|---|
| Line | Each line executed at least once | if a or b: — only one of a/b tested |
| Branch | Each if/else arm taken | if a and b: — never tested a=T, b=F |
| Condition | Each boolean sub-expression both T and F | Masking: short-circuit hides some |
| MC/DC | Each condition independently flips the outcome | Nothing — this is the aviation standard |
| Mutation | Tests kill injected bugs | → mutation-test-suite-optimizer |
Default target: branch coverage. MC/DC for safety-critical. Mutation for "is this suite actually good."
Step 1 — Get the gap report
| Ecosystem | Branch coverage command |
|---|---|
| Python | pytest --cov=src --cov-branch --cov-report=term-missing |
| Java | JaCoCo — mvn jacoco:report, look at "branches missed" |
| JS/TS | jest --coverage (Istanbul) — "% Branch" column |
| Go | go test -cover is line-only; use -covermode=count + gocov for branches |
| C/C++ | gcov -b / llvm-cov |
Output: file → uncovered lines + uncovered branches. The branches are the interesting part.
Step 2 — Rank the gaps
Not all uncovered code is equal. Rank by risk × effort:
| Factor | Weight | How to measure |
|---|---|---|
| Code churn (recently changed) | High | `git log --since="3 months ago" --oneline -- |
| Complexity (cyclomatic) | High | Radon/SonarQube/etc — complex & untested = risky |
| Error handling path | High | except:, if err != nil — errors hide here |
| Public API surface | Medium | Externally reachable |
| Auto-generated / boilerplate | -High | __repr__, getters — low value |
| Defensive dead code | -High | if x is None: that's never None by construction |
Top of the list: complex error-handling in recently-churned public APIs. Bottom: generated __eq__ methods.
Step 3 — Construct the hitting test
For each targeted gap, reverse-engineer the input:
Uncovered branch: pricing.py:47 — if customer.tier == "enterprise" and region == "eu": [TRUE branch never taken]
Path to this line: called from calculate_price(customer, items) → _apply_discounts(customer, subtotal) → line 47.
What needs to be true: customer.tier == "enterprise" AND region == "eu". Where does region come from? customer.billing_address.country mapped through COUNTRY_TO_REGION.
Test:
def test_enterprise_eu_discount_applied():
customer = Customer(
tier="enterprise",
billing_address=Address(country="DE"), # DE → eu in COUNTRY_TO_REGION
)
price = calculate_price(customer, items=[Item(base=100.0)])
# Branch was dead because no test had an enterprise customer in the EU.
# The discount is 15% per the body of the branch.
assert price == 85.0
The assertion isn't assert True — it checks what the branch does, not just that it ran.
Step 4 — Uncoverable code
Some gaps shouldn't be closed:
| Pattern | Verdict |
|---|---|
if sys.platform == "win32": |
Covered on Windows CI. # pragma: no cover on other platforms. |
raise AssertionError("unreachable") |
It's unreachable. That's the point. Exclude. |
except MemoryError: |
Can't reliably trigger. Document the manual test. |
Logging, __repr__, debug helpers |
Low value. Configurable exclusion. |
if TYPE_CHECKING: |
Never runs at runtime. Exclude. |
Mark these explicitly (# pragma: no cover + a reason). Don't chase 100%.
Do not
- Do not write tests that hit lines without asserting behavior.
call_function(); assert Trueraises coverage and tests nothing. Every new test asserts the effect of the code it covers. - Do not chase 100% line coverage. Diminishing returns past ~85% — the last 15% is boilerplate, defensive code, and platform-specific paths. Chase branch coverage and mutation score instead.
- Do not test auto-generated code.
@dataclass__eq__works. Don't test the language. - Do not ignore why a branch was uncovered. Sometimes it's dead code (→
dead-code-eliminator). Sometimes it's a condition that's always False by construction — that's a bug or a simplification opportunity, not a test gap.
Output format
## Current coverage
Line: <%> Branch: <%> (<tool + config>)
## Gap ranking
| File:line | Type | Risk | Churn | Complexity | Priority |
| --------- | ---- | ---- | ----- | ---------- | -------- |
## Targeted tests
### Gap: <file:line> — <description>
Path condition: <what must be true to reach this>
Test:
<code>
Expected coverage delta: +<N> branches
## Excluded
| File:line | Why uncoverable | Marked with |
| --------- | --------------- | ----------- |
## Projected
After these tests: Line <%> → <%>, Branch <%> → <%>
More from santosomar/general-secure-coding-agent-skills
dependency-resolver
Diagnoses and resolves package dependency conflicts — version mismatches, diamond dependencies, cycles — across npm, pip, Maven, Cargo, and similar ecosystems. Use when install fails with a resolution error, when two packages require incompatible versions of a third, or when upgrading one dependency breaks another.
4configuration-generator
Generates configuration files for services and tools (app config, logging config, linter config, database config) from a brief description of desired behavior, matching the target format's idioms. Use when bootstrapping a new service, when the user asks for a config file for a specific tool, or when translating config intent between formats.
3ci-pipeline-synthesizer
Generates CI pipeline configs by analyzing a repo's structure, language, and build needs — GitHub Actions, GitLab CI, or other platforms. Use when bootstrapping CI for a new repo, when porting from one CI to another, when the user asks for a pipeline that builds and tests their project, or when wiring in security gates.
3api-design-assistant
Reviews and designs API contracts — function signatures, REST endpoints, library interfaces — for usability, evolvability, and the principle of least surprise. Use when designing a new public interface, when reviewing an API PR, when the user asks whether a signature is well-designed, or when planning a breaking change.
2code-refactoring-assistant
Executes refactorings — extract method, inline, rename, move — in small, behavior-preserving steps with a test between each. Use when the user wants to restructure working code, when cleaning up after a feature lands, or when a smell has been identified and needs fixing.
2code-smell-detector
Identifies code smells — structural patterns that correlate with maintainability problems — and explains why each matters in context. Use when reviewing a PR for structural quality, when the user asks what's wrong with a piece of code that isn't buggy, or when prioritizing refactoring targets.
2