review-testing
Review test code for quality, design, and completeness after implementing a feature or fixing a bug.
Skill by Garrick Aden-Buie (@gadenbuie)
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/posit-dev-review-testing
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, testing, code-review
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/review-testing
What's inside
- Skill name
review-testing- Description
- Review test code for quality, design, and completeness after implementing a feature or fixing a bug. Use when the user asks to "review my tests", "check my test quality", "are these tests good enough", "review testing", or after completing a feature implementation that includes tests. Also use when tests feel brittle, flaky, or superficial. Cross-references production code to find coverage gaps.
- License
- MIT
- Metadata
- author: Garrick Aden-Buie (@gadenbuie) · version: 0.1
- Instructions
- 150 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
You are reviewing test code written alongside a feature implementation or bug fix. Ensure the tests are well-designed, thorough, and maintainable — not just that they pass. Tests that merely mirror implementation details create false confidence and become a maintenance burden during refactoring.
## Review Scope
Identify what to review:
1. **Find changed test files** on the current branch (relative to the base branch).
2. **Find the production code** those tests cover — trace imports, function calls, and file naming conventions to map tests to their targets.
3. **Find related existing tests** for the same modules or functions that weren't changed — these may need updates or reveal gaps.
Read test files first, before production code. If you can infer the feature's requirements and edge cases from the tests alone, that's a sign the tests are well-written. If you need to read the implementation to understand what the tests are doing, that's a finding worth reporting.
## What Makes a Test Valuable
Weigh each test against four qualities:
**Regression protection** — Does this test actually catch bugs? A test that exercises trivial code or skips complex branches protects against nothing. Check: does the test touch business-critical logic, or only verify the happy path of a simple getter?
**Refactoring resilience** — Will this test break when someone restructures code without changing behavior? Tests coupled to internal method names, call sequences, or private state punish every cleanup with false failures, eroding trust in the suite.
**Fast feedback** — Unit tests should run in milliseconds. If a test hits the filesystem, network, or database unnecessarily, that's a design issue. But don't confuse speed with value — an integration test verifying a real database query is better than a fast unit test that mocks everything and verifies nothing.
**Maintainability** — Can someone unfamiliar with this code read the test and understand what it verifies and why? Tests with sprawling setup, cryptic names, or deeply nested mocking fail this check.
## Review Areas
### 1. Assertion Completeness
The most common weakness in generated tests: asserting only the obvious output and missing the full "blast radius" of a state change.
When a test triggers an action, ask what *else* changed. If a test adds an item to a cart, does it only check the item count? Or does it also verify the price calculation, subtotal update, and that other items are unaffected?
**Flag when:**
- A test asserts a return value but ignores side effects
- A test checks that an operation succeeded but not that it produced the right result
- A test verifies the happy path but skips boundary conditions (empty inputs, nulls, maximum values, off-by-one)
- Error-path tests only check that an error was thrown, not the error message, type, or cleanup behavior
### 2. Test Structure
Each test should have exactly one Arrange-Act-Assert cycle. If a test acts and asserts multiple times in sequence, it's testing multiple behaviors and should be split.
**Flag when:**
- A test has multiple act phases (testing a workflow, not a behavior)
- The arrange phase is so large the actual behavior being tested is buried
- Assertions appear inside setup helpers or utility functions (hides what's being verified)
- Test logic contains conditionals or loops — tests should be straight-line code
### 3. Fixture and State Management
How test data is created determines whether the suite is maintainable at scale. **Inline setup** (data created in the test body) is fine for simple tests but painful when constructor signatures change across many tests. **Implicit setup** (shared `beforeEach`/`setUp` blocks) eliminates duplication but obscures what each test actually depends on. **Delegated setup** (factory functions or builders called explicitly) keeps tests readable while centralizing construction logic.
**Flag when:**
- A shared setup block creates objects most tests don't use
- Tests depend on external files, database state, or globals defined elsewhere ("Mystery Guest" — everything a test needs should be visible in its body or one function call away)
- Tests assume resources exist without creating them (files, database records, environment variables)
- Tests mutate shared state without cleanup, causing order-dependent failures
### 4. Mocking Boundaries
Mocks are essential for isolation, but overuse turns tests into mirrors of the implementation.
**The key principle:** mock at architectural boundaries, not at every function call. Use stubs (canned data) for query-type dependencies and mocks (interaction verification) only for commands with side effects like sending emails or writing to external systems.
Respect the codebase's existing mocking convention. Flag inconsistency within the project, not deviation from a universal rule.
**Flag when:**
- A test mocks types it doesn't own (third-party libraries, framework internals) — when the library updates, the mock passes against outdated assumptions. Prefer: thin adapters, real implementations in integration tests, or official testing utilities (MemoryRouter, test databases, in-memory caches).
- Mock density is high — 4+ mock configurations suggests too many responsibilities in the production code
- A test verifies call counts or argument sequences on internal methods (couples the test to *how* the code works, not *what* it does)
- Stubs are being verified (checking a stub was called tests implementation, not behavior)
### 5. Test Smells
| Smell | What It Looks Like | Why It Matters |
|---|---|---|
| **Assertion Roulette** | Multiple assertions with no failure messages | Can't tell which assertion broke without debugging |
| **Eager Test** | One test exercises several unrelated methods | Failures are ambiguous — which behavior broke? |
| **Lazy Test** | Multiple tests call the same method with identical inputs | Redundant maintenance cost, no coverage gain |
| **Sleepy Test** | Hard-coded `sleep()`/`Sys.sleep()`/`setTimeout()` | Flaky in CI, slow everywhere. Use polling or explicit waits. |
| **Rotten Green** | Assertions inside `try`/`tryCatch` or conditional branches | Test always passes because the assertion is never reached |
| **Sensitive Equality** | Asserting against `toString()`/`print()` output | Breaks on formatting changes; assert structural properties instead |
| **Print Statement** | `print()`/`console.log()` instead of assertions | Debugging leftovers that verify nothing |
| **Snapshot Abuse** | Snapshots as a substitute for behavioral assertions | Any change triggers failure, developers blindly update. Good uses: one snapshot of an HTML component's structure (not every prop combination), error message text, CLI output. Bad: snapshotting entire objects or rendering every variant. |
| **Implementation Mirror** | Expected values computed using the same logic as production code | Test and production code will always agree — even when both are wrong. Hardcode expected values from a known-good source. |
### 6. Naming and Readability
Test names should describe behavior, not implementation. A well-named test suite reads like a feature specification.
**Flag when:**
- Test names reference internal method names (e.g., `test_processData_returns_true`) — break on rename
- Test names are generic (`test1`, `test_it_works`, `test_basic`)
- The name doesn't communicate the scenario or expected outcome
Prefer behavioral names: `test_expired_subscription_blocks_access`, `delivery_with_past_date_is_invalid`, `empty_cart_shows_zero_total`.
### 7. Coverage Gaps
Cross-reference production code changes against the test suite:
- Are there branches or conditions no test exercises?
- Are error paths tested? (Not just "does it throw" but "does it throw the right thing and clean up properly")
- Are edge cases covered? (Empty collections, null/NA/None/undefined, boundary values, concurrent access if applicable)
- If production code changed existing behavior, were existing tests updated?
Walk through the implementation and note every decision point — each `if`, `match`, `switch`, error handler, or early return. Check whether the test suite exercises both sides of that decision.
When reviewing R tests using `testthat`, check if the `r-testthat` skill is available and invoke it for R-specific conventions and patterns.
## Response Format
```
## Summary
[Overall assessment: How well do these tests protect the codebase?]
## Critical Issues (Blocking)
[Tests that provide false confidence or will cause real problems.]From posit-dev/skills, MIT.
More from posit-dev/skills
- 0.815score
r-cli
Garrick Aden-Buie (@gadenbuie)
Comprehensive R package for command-line interface styling, semantic messaging, and user communication.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
shiny-py-optimize
Garrick Aden-Buie (@gadenbuie)
Diagnose and fix performance problems in Shiny for Python apps — slow startup, sluggish interactions, blocking operations, and apps that struggle beyond a…
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
r-lifecycle
Garrick Aden-Buie (@gadenbuie)
Guidance for managing R package lifecycle according to tidyverse principles using the lifecycle package.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
pr-create
Garrick Aden-Buie (@gadenbuie)
Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
shiny-r-optimize
Garrick Aden-Buie (@gadenbuie)
Diagnose and fix performance problems in Shiny for R apps — slow startup, sluggish interactions, long-running blocking operations, and apps that struggle…
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
r-testthat
Garrick Aden-Buie (@gadenbuie)
Best practices for writing R package tests with testthat version 3+.
SkillAFreshness: A★ 547Claude Code +9 - 0.809score
r-mirai
Charlie Gao (@shikokuchuo)
Help users write correct R code for async, parallel, and distributed computing using mirai.
SkillAFreshness: A★ 547Claude Code +9 - 0.809score
critical-code-reviewer
Garrick Aden-Buie (@gadenbuie)
Rigorously review code or pull requests for correctness, security, accessibility, maintainability, tests, and edge cases.
SkillAFreshness: A★ 547Claude Code +9 - 0.809score
r-cran-extrachecks
Garrick Aden-Buie (@gadenbuie)
Prepare R packages for CRAN submission by checking for common ad-hoc requirements not caught by devtools::check().
SkillAFreshness: A★ 547Claude Code +9 - 0.809score
r-cran-status
Garrick Aden-Buie (@gadenbuie)
Look up an R package's live status on cran.r-project.org - submission/review state (queue, human review, waiting, archived, past version's fate) or R CMD…
SkillAFreshness: A★ 547Claude Code +9 - 0.809score
describe-design
Garrick Aden-Buie (@gadenbuie)
Research a codebase and create architectural documentation describing how features or systems work.
SkillAFreshness: A★ 547Claude Code +9 - 0.806score
pr-threads-resolve
Barret Schloerke (@schloerke)
Bulk resolve unresolved PR review threads on the current branch’s PR — typically after threads have been addressed manually or via /pr-threads-address
SkillAFreshness: A★ 547Claude Code +9
Signals
- Stars
- 547
- Forks
- 57
- Open issues
- 6
- Last commit (this folder)
- Oct 6, 2026 (21 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- Version
- 0.1
- License
- MIT
- Repository
- github.com/posit-dev/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from Garrick Aden-Buie (@gadenbuie)
- 0.815score
shiny-r-optimize
Garrick Aden-Buie (@gadenbuie)
Diagnose and fix performance problems in Shiny for R apps — slow startup, sluggish interactions, long-running blocking operations, and apps that struggle…
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
shiny-py-optimize
Garrick Aden-Buie (@gadenbuie)
Diagnose and fix performance problems in Shiny for Python apps — slow startup, sluggish interactions, blocking operations, and apps that struggle beyond a…
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
r-testthat
Garrick Aden-Buie (@gadenbuie)
Best practices for writing R package tests with testthat version 3+.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
r-lifecycle
Garrick Aden-Buie (@gadenbuie)
Guidance for managing R package lifecycle according to tidyverse principles using the lifecycle package.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
r-cli
Garrick Aden-Buie (@gadenbuie)
Comprehensive R package for command-line interface styling, semantic messaging, and user communication.
SkillAFreshness: A★ 547Claude Code +9 - 0.815score
pr-create
Garrick Aden-Buie (@gadenbuie)
Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes.
SkillAFreshness: A★ 547Claude Code +9
Cite this page
review-testing skill. Agent Mart. https://agentmart.dev/skills/posit-dev-review-testing (last updated 2026-10-24)