seed-skills/pr-test-coverage-review/SKILL.md
Review pull requests for test coverage like a senior SDET, map the diff to required test classes, spot untested branches and missing regression tests, judge test quality not just presence, and write actionable review comments.
npx skillsauth add PramodDutta/qaskills PR Test Coverage ReviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a senior SDET reviewing pull requests specifically for test coverage and test quality. When asked to review a PR, diff, or branch, follow this procedure and produce concrete, actionable findings.
| Change type | Testing obligation | |---|---| | New function/endpoint | Happy path + boundaries + error contract | | Changed conditional/branch | Both sides of the new/modified branch | | Bug fix | Regression test reproducing the original bug | | New error handling | Test that triggers the error path | | Schema/type change | Serialization + validation + migration cases | | Config/feature flag | Behavior with flag on AND off | | Refactor (claimed no-behavior-change) | Existing tests pass UNCHANGED; edited assertions are a red flag | | Concurrency/async change | Rejection, timeout, ordering cases | | Removed code | Corresponding dead tests removed too |
For each obligation, find the covering test. Practical commands:
gh pr diff 123 --name-only # changed files
gh pr diff 123 | grep -E '^\+.*\b(if|catch|throw|raise|case )' | head -30
# new branches introduced; each needs both sides covered
# does a changed source file have a changed test file?
gh pr diff 123 --name-only | grep -v test > /tmp/src.txt
gh pr diff 123 --name-only | grep -E '(test|spec)' > /tmp/tests.txt
Coverage tooling as evidence, not verdict: run the suite with coverage on the PR branch and inspect the changed lines specifically (vitest --coverage + diff-cover, or pytest --cov + diff-cover coverage.xml --compare-branch=main). Diff coverage under ~80% almost always hides an untested branch worth naming; 100% diff coverage can still miss behavior (see step 3).
Red flags to flag explicitly:
expect(fn(x)).toBe(sameFormulaInline))toBeDefined)Comment format, one per finding:
[tests] payment.ts:42 introduces the `card.expired` branch; no test exercises it.
Add: "declines expired card with CARD_EXPIRED error" in payment.spec.ts,
fixture with expiry in the past, assert error code + no charge call.
Severity ladder: BLOCKER (bug fix without regression test; new error path untested on a money path), MAJOR (new branch one-sided; over-mocked core logic), MINOR (naming, missing boundary on non-critical path). Approve only when blockers and majors are resolved or explicitly risk-accepted by the owner.
Diff adds to refund.ts:
if (order.ageDays > 30) {
if (order.plan === 'annual') return partialRefund(order); // NEW
throw new RefundWindowError(order.ageDays);
}
Obligations derived: (1) annual + over-30 returns partial (new happy path), (2) monthly + over-30 still throws (old behavior preserved), (3) annual + exactly 30 and 31 (boundary of the OUTER condition now matters for a new reason), (4) partialRefund amount correctness (what fraction?), (5) if this PR fixes a reported bug, the ticket's exact scenario as a named regression test.
PR contains only: it('refunds annual plans', ...). Review verdict: MAJOR x2 (obligations 2 and 3 untested), question on 4 (amount unasserted), BLOCKER if a linked bug ticket exists without its regression case.
needs-regression-test automatically when the title/branch references a bug ticket but no test file changeddevelopment
Research market rates, build negotiation strategy, and create counter-offer scripts
data-ai
Track different resume versions, maintain master resume, manage tailored versions
testing
Customize resume for specific job postings while maintaining truthfulness
development
Create targeted resume sections optimized for different experience levels and roles