Create or fix tests for existing Grove code examples. Use when the user asks to "add a test", "create a test", "fix this test", "update the test", "the test doesn't match the output", "test is failing", or wants to add test coverage for an existing example or fix a broken test.
68
83%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Begin your first response with: [grove-test-091435b6]
Create new tests for existing code examples, or diagnose and fix broken tests.
This is a lighter-weight skill than /grove-create — it focuses on the test
side only and runs a single test pass (no subagent).
Do NOT use when:
/grove-create/grove-run/grove-migrate/grove-run (heuristic: if the error contains ECONNREFUSED,
MongoServerSelectionError, timeout, or Missing: sample_, it's a
runtime issue)Before Step 1, check whether the Grove VS Code extension has dropped a
handoff file at .claude/grove-handoff.json in the workspace root. If the
file exists and skill equals grove-test:
Delete the handoff file immediately after reading it. Single-use.
Check the payload before using it. If a check fails, surface what's wrong to the writer, recommend they update the Grove VS Code extension (or file an issue if it's already current), and ask whether to proceed without the handoff. If they confirm, fall through to Step 1.
version must equal 1. A higher number means
the extension is ahead of this skill. Example message:
Found a Grove extension handoff with
version: {n}, but this skill only understands version 1. The extension is likely newer than the skill. Proceed without the handoff?
version, skill, trigger, context. The
context object must contain the fields listed in the schema for
the matching trigger below. Example message:
The Grove extension handoff at
.claude/grove-handoff.jsonis malformed: {brief reason, e.g. "missing context.sourceFile"}. This is likely an extension bug — please file an issue. Proceed without the handoff?
Branch on trigger. The JSON block under each branch is the
expected payload schema, not just an illustrative sample — use
it as the reference for what fields must be present:
trigger: "untested-source" — snipped source file has no testFull envelope:
{
"version": 1,
"skill": "grove-test",
"trigger": "untested-source",
"timestamp": "ISO-8601",
"workspaceRoot": "/absolute/path",
"context": {
"sourceFile": "code-example-tests/python/pymongo/examples/crud/insert_one.py",
"projectPath": "code-example-tests/python/pymongo",
"language": "python",
"snippetNames": ["example", "setup"]
}
}This is Create mode with the source file identified. Skip Step 1 (task determination — it's a create, not a fix) and use:
sourceFile → the example file to read in Step 3 (Analyze the Example).language → the target suite for conventions lookup in Step 2.projectPath → the Grove project root for locating the tests/
directory.snippetNames → the snippets already marked in the source (may be
empty for suites like mongosh that don't require Bluehawk tags). When
non-empty, the test's Bluehawk markup should reference the same names
where appropriate so input/output snippets align.Propose the test file location based on the source path and the
language's convention (e.g., examples/crud/insert_one.py →
tests/crud/test_insert_one.py). Confirm the location with the writer
before proceeding to Step 2.
Echo one line confirming the captured context, e.g.:
Got handoff from extension: adding a test for {sourceFile} ({language}).
Proceed from Step 2 (Load Conventions) with the target file identified.
If the handoff file is absent or skill doesn't match, proceed
normally from Step 1.
Parse the user's request to identify the mode:
Create mode — the user provides an example file path or says "add a test for X":
Fix mode — the user provides a test file path or says "fix this test":
Read the CLAUDE.md file in the target language's driver directory. Also read
code-example-tests/CLAUDE.md for cross-language patterns (Bluehawk, ellipsis
patterns, sample data utilities).
Read the "Comparison API" section in
.claude/skills/grove-create/references/conventions-{language}.md (matching
the target language) for the full Expect API reference — method signatures,
import paths, ellipsis pattern syntax, and schema validation options.
Read the example file (and the test file, if fixing). Gather this information:
If fixing, also:
Check existing test files in the topic area:
tests/{topic}/**/*.test.js (or equivalent for the language)it
block or create a new fileit blocksit blocksWrite the test following the language's conventions:
Expect if file-based comparison is neededafterEach to drop the test database (not sample databases)it block:
Choose the right validation approach based on the scenario. See the "Comparison API" section in the target language's conventions file for the full method signatures, import paths, and ellipsis pattern reference:
| Scenario | Approach |
|---|---|
| Output file exists | shouldMatch(filepath) |
| Simple return value (string, number, boolean) | Jest expect(result).toBe(expected) |
| Need to ignore dynamic fields | Chain .withIgnoredFields(...) before shouldMatch |
| Order doesn't matter | Chain .withUnorderedSort() (default in JS) |
| Order matters (sorted results) | Chain .withOrderedSort() |
| Variable results, structure matters | shouldResemble(expected).withSchema({...}) |
For mongosh, the Expect API is different — use outputFromExampleFiles()
instead of that(). See the mongosh conventions file for details.
Do not modify the example file without checking with the user first. The example is written to illustrate a specific concept — changing it may break the docs intent. If the fix requires changing the example (e.g., the example accesses a field as the wrong type), explain the issue and its implications to the user and let them decide how to proceed.
Based on the diagnosis from Step 3:
withIgnoredFields / withUnorderedSort as neededdescribeWithSampleData / itWithSampleData in JS)Example fix walkthrough:
Error: ComparisonResult — field mismatch at [0]._id
Expected: "507f1f77bcf86cd799439011"
Received: "683a1f2b4e9c..."The output file has a hardcoded _id. Two options:
"..." in the output file (preferred).withIgnoredFields('_id') to the Expect chain in the testOutput files are not required. If the test uses file-based comparison and no output file exists, you may create one:
If the example's output is not shown in documentation and the return value is
simple, define the expected output inline in the test and use the Comparison
API (e.g., Expect.that(result).shouldMatch(expectedObject)) rather than
framework-specific assertions. This keeps all validation on a single path.
Run the test once to verify it passes. Use the test commands from /grove-run
Step 3 (the canonical source for per-language test commands). For JavaScript:
cd code-example-tests/{driver-dir} && npm test -- -t '{test name}'If it fails, diagnose and fix (loop back to Step 5, max 3 attempts). After 3 failed attempts, stop and report the remaining error to the user with the full error output, what you tried, and what you suspect the root cause is. Do not continue trying.
Idempotency fixes: Run the test once. If it passes, stop — do not run
consecutive passes. grove-test runs a single pass because its focus is test
correctness, not idempotency. Tell the user to run /grove-run to verify
idempotency.
Provide a report headed with Skill: grove-test:
// :remove: so it doesn't appear
in the docs snippet._id values: Replace them with "..." ellipsis
patterns. Dynamic fields like _id, timestamps, and ObjectIds should never
be hardcoded in expected output.describeWithSampleData() / itWithSampleData() so it auto-skips when the
required sample database is unavailable, rather than failing.5985af5
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.