PluginBench
Skill
Pass
Audit score 90

test-guard

amelnagdy/guard-skills

Review AI-generated test code against universal testing rules before it ships.

What is test-guard?

Test Guard enforces nine rules to prevent AI-generated test bloat: testing behavior not implementation, mocking only at system boundaries, eliminating duplicate tests, and justifying every test's existence. Use it reactively after an agent writes or edits tests, or proactively before test writing begins.

  • Flags tests that assert implementation details instead of observable behavior
  • Identifies unjustified mocks of internal functions and classes
  • Detects duplicate data-driven tests that should be merged
  • Removes tests that only verify framework guarantees or trivial logic
  • Ensures test names describe scenarios, not function signatures
  • Preserves production regression tests as sacred and exempt from deletion

How to install test-guard

npx skills add https://github.com/amelnagdy/guard-skills --skill test-guard
Claude Code
Cursor
Windsurf
Cline

How to use test-guard

  1. 1.After an agent writes, edits, or generates test code, invoke this skill to review the changes
  2. 2.Read the test code and check each test against the nine rules provided
  3. 3.Report violations concisely with rule number, location, and suggested fix
  4. 4.If invoking before test writing, apply the rules as you write to prevent violations upfront
  5. 5.Adapt the rules to your project's testing conventions by checking CLAUDE.md, AGENTS.md, or testing docs first
  6. 6.Consult the language-specific reference (pytest.md, phpunit.md, jest.md) for concrete patterns
  7. 7.For LLM applications, also apply the three extra rules in llm-app-testing.md

Use cases

Good for
  • Review pytest test files before committing to catch mock-heavy unit tests that hide integration bugs
  • Validate Jest/Vitest test suites to eliminate near-duplicate tests differing by one input value
  • Audit PHPUnit/Pest tests to ensure mocks are only at network, database, and filesystem boundaries
  • Guide test writing before an agent begins, preventing violations from being written in the first place
  • Review PR diffs containing test changes to enforce consistent testing patterns across the team
Who it's for
  • Developers using AI coding agents (Claude Code, Cursor) to write or refactor tests
  • Teams adopting agent-assisted development who want to prevent test bloat and maintenance drag
  • QA engineers reviewing AI-generated test suites for quality and coverage
  • Tech leads enforcing testing standards across projects with multiple test stacks

test-guard FAQ

When should I use Test Guard?

Use it reactively after an agent writes, edits, or generates tests, before presenting, committing, or merging. You can also invoke it proactively before test writing to guide the agent and prevent violations from being written in the first place.

What test frameworks does Test Guard support?

pytest (Python), PHPUnit/Pest (PHP), Jest/Vitest (JavaScript/TypeScript), and Go testing. It recognizes test files by naming convention (test_*.py, *_test.py, *Test.php, *.test.ts, *.spec.js, *_test.go) and directory structure (tests/, __tests__/, spec/).

Does Test Guard override my project's testing rules?

No. Project-specific testing rules in CLAUDE.md, AGENTS.md, or testing docs always win. Check those first, then apply Test Guard's universal rules where they don't conflict.

What is the most common violation Test Guard catches?

Mock-heavy unit tests that assert internal function calls instead of observable behavior (Rule 1 and 2). These tests break on every refactor while catching nothing real, and they hide integration bugs worth catching.

Can I ignore a Test Guard violation?

Use judgment based on severity. Must-fix violations (Rules 1, 2, 8) hide real bugs. Should-fix violations (Rules 3, 4, 5, 7) cause maintenance drag. Production regression tests (Rule 6) are sacred and never deleted. Rule 9 is worth noting but doesn't block small changes.

Full instructions (SKILL.md)

Source of truth, from amelnagdy/guard-skills.


name: test-guard description: "Review generated or changed test code against universal testing rules before it ships. Best used reactively after an agent writes, edits, generates, or refactors tests, before presenting, committing, or merging them. Use for pytest (test_*.py, *_test.py), PHPUnit/Pest (Test.php), Jest/Vitest (.test.ts, .spec.js), Go (_test.go), files under tests/, tests/, or spec/, and review requests like 'write tests for X', 'add tests', 'test this', 'review these tests', or PR diffs containing tests. Can also guide test writing when explicitly invoked before the work. This skill is the quality gate that prevents AI-generated test bloat."

Test Guard

You are reviewing generated or changed test code before it ships. Enforce the rules below after the first test-writing pass and before the tests are presented, committed, or merged. Be a sharp reviewer, not a pedantic one: flag what wastes maintenance effort or hides real bugs, ignore cosmetic preferences.

These rules exist because coding agents over-generate tests. The common failure modes: mock-heavy unit tests that assert implementation details, near-duplicate test bodies that differ by one value, and tests that re-verify the framework instead of the project's logic. Each looks productive in a diff and costs maintenance forever.

When this skill activates

  • A coding agent has just written new test functions or test files, in any language
  • You are editing existing tests
  • You are reviewing a diff that contains test changes
  • The user asks you to write, add, or review tests

Adapt to the project first

These rules are universal, but their application is not. Before reviewing:

  1. Check the project's own agent instructions (CLAUDE.md, AGENTS.md) and testing docs. Project-specific testing rules win over this skill when they conflict.
  2. Identify the test stack, then read the matching reference for concrete patterns:
  3. If the project calls LLM APIs, uses agent frameworks, or wires up observability/telemetry, also read references/llm-app-testing.md — it adds three rules specific to LLM applications.
  4. Map the project's system boundaries: network calls, databases, filesystem, clock and randomness, third-party SDKs, LLM APIs. Existing fixtures and test helpers usually reveal where the project already draws these lines.

What to do

  1. Read the test code: the diff, the new file, or the section being modified.
  2. Check each test against the rules below.
  3. Report violations concisely: rule number, location, why it violates, suggested fix.
  4. If the user explicitly invokes this skill before test writing, apply the rules as you write — don't write violations and then flag them.

When writing new tests, ask for each test: "What specific bug does this catch that no other test in this suite catches?" If you can't answer clearly, don't write it.

The Nine Rules

Rule 1: Test behavior, not implementation

Test what code does from the caller's perspective. Assert return values and observable side effects. Never assert that an internal helper was called with specific arguments — that test breaks on every refactor while catching nothing.

Violation pattern: asserting a mock of an internal function was called, where that function is not a system boundary. Fix: assert the return value or the state change the caller observes.

Rule 2: Every mock must be justified

Mock only at system boundaries: network and HTTP calls, LLM APIs, databases, filesystem I/O on external files, clock and randomness, third-party SDKs. Never mock internal classes or helper functions to isolate a "unit" — the seams you create hide the integration bugs worth catching.

When you mock a boundary, assert what the caller does with the response, not that the mock received specific arguments.

Rule 3: One scenario per test, data-driven for variants

If two or more tests share identical setup and differ only in input/output values, merge them into one data-driven test (@pytest.mark.parametrize, PHPUnit #[DataProvider], Jest test.each).

When separate tests ARE correct: different setup, different assertions, different mock configurations, or genuinely different scenarios that happen to exercise the same function.

Rule 4: Every test must justify its existence

Ask: "What bug does this catch that no other test catches?" Delete tests that only catch typos, verify default values of data classes, or test trivial pass-through logic.

Common unjustified tests: constructors setting attributes, a function rejecting input the type system already forbids, string formatting of log messages, a constant equaling its literal value.

Rule 5: Name tests for the scenario

Pattern: test_<scenario>_<expected_outcome>. The name should read like a requirement, not echo the function signature.

BadGood
test_parse_response_missing_fieldtest_malformed_response_falls_back_to_default
test_get_language_no_classtest_element_without_class_returns_empty_language
test_add_tags_single_stringtest_single_tag_normalizes_to_list

Rule 6: Production regression tests are sacred

Tests that reproduce a real production bug are always justified. Reference the incident (date, issue ID, or short description) in the name or a comment, and never delete them. They are exempt from Rule 4 — their justification is the incident.

Rule 7: No tests for framework guarantees

Don't test that the validation library validates, the ORM commits, the router returns 404, or the test framework's fixtures work. Test your logic that sits on top of the framework.

Violation pattern: a test that would still pass if you deleted all the project's custom code and kept only framework defaults.

Rule 8: State and value objects are real, never mocked

Never mock a data model, DTO, entity, or state object. Construct a real instance. Mocking state hides field-name typos and validation errors — exactly the bugs worth catching. If constructing the real object is painful, that is design feedback, not a reason to mock; add a small builder or factory helper.

Rule 9: Infrastructure under test gets real infrastructure

When database queries, schema behavior, or persistence logic is the subject of the test, run against a real test database with real migrations applied via fixtures. Mocking the session there tests nothing. Mocking the database is fine when persistence is only a side effect of the behavior under test.

Reporting format

When flagging violations, use this format:

**Rule N violation** in `tests/path/file.ext::<test_name>`
- What: <one sentence describing the violation>
- Fix: <one sentence describing what to do instead>

Group violations by file. If a file has no violations, don't mention it.

Severity guide

Not all violations are equal. Use judgment:

  • Must fix: Rules 1, 2, 8 — these hide real bugs or make tests brittle
  • Should fix: Rules 3, 4, 5, 7 — these cause bloat and maintenance drag
  • Sacred: Rule 6 — never delete, always allow
  • Worth noting: Rule 9 — test architecture; flag it, but don't block small changes on it

References

  • references/pytest.md — Python/pytest patterns: parametrize, fixtures, mock boundaries, real Pydantic instances
  • references/phpunit.md — PHP/PHPUnit/Pest patterns, including WordPress and WooCommerce test boundaries
  • references/jest.md — Jest/Vitest patterns: test.each, module mocks, msw, snapshot discipline
  • references/llm-app-testing.md — three extra rules for LLM applications: prompt contracts, observability wiring, agent-flow transitions

What this skill does NOT do

  • It does not run tests. Use the project's test runner for that.
  • It does not enforce code style — that's the linter's job.
  • It does not decide what to test — only how to test it.
  • It does not flag pre-existing violations in files you're not touching, unless asked to audit.

Related skills

More from amelnagdy/guard-skills and the wider catalog.

WOwoo-guard logo

woo-guard

amelnagdy/guard-skills

Review generated or changed WooCommerce code — extensions, payment and shipping integrations, checkout customizations, and order/product logic — before it ships. Best used reactively after an agent writes, edits, or reviews code touching WooCommerce APIs: wc_get_order, wc_get_orders, wc_get_product, WC() cart or session, woocommerce_* hooks, Store API endpoints, payment gateways, order or product meta, HPOS, subscriptions, or bookings. Use on 'review this Woo plugin', 'is this HPOS compatible', or after tasks like 'write a WooCommerce extension', 'add a checkout field', 'hook into the order flow', or 'update stock'. Enforces HPOS-safe order access, CRUD over direct meta, feature-compatibility declarations, server-side checkout validation, money-handling discipline, and hooks over template overrides. DO NOT USE for WordPress code without WooCommerce APIs (use wp-guard), generic code review (use clean-code-guard), test review (use test-guard), or store configuration and admin-screen questions.

703 installsAudited
WPwp-guard logo

wp-guard

amelnagdy/guard-skills

Review generated or changed WordPress code — plugins, themes, and blocks — before it ships. Best used reactively after an agent writes, edits, or reviews code touching WordPress APIs: add_action/add_filter, shortcodes, meta boxes, AJAX handlers, REST routes, WP_Query or $wpdb, widgets, or WP-CLI commands. Use on 'review this plugin', 'is this safe to ship', 'make this translatable', 'speed up this query', or after tasks like 'write a plugin' or 'add an endpoint/shortcode/meta box'. Enforces escaping and sanitization, nonces plus capability checks, prepared database queries, core-API-first development, translation-ready strings, and query/caching discipline. DO NOT USE for WooCommerce-specific order, product, or checkout logic (use woo-guard), non-WordPress PHP, generic code quality review (use clean-code-guard), test code review (use test-guard), server or hosting configuration, or conceptual WordPress questions.

704 installsAudited
CLclean-code-guard logo

clean-code-guard

amelnagdy/guard-skills

Review production code against Clean Code, SOLID, DRY, KISS, YAGNI, and LLM-specific failure modes before shipping.

1.7k installsAudited
DOdocs-guard logo

docs-guard

amelnagdy/guard-skills

Verify documentation accuracy against source code before publishing.

1.4k installsAudited
ANangular-component logo

angular-component

analogjs/angular-skills

Create modern Angular v20+ standalone components with signals, OnPush detection, and accessibility built-in.

9.2k installsAudited
ANangular-di logo

angular-di

analogjs/angular-skills

Implement dependency injection in Angular v20+ with inject(), tokens, and provider configuration.

5.0k installsAudited