Use when writing or adding Vitest tests for Positron src/vs/ code, checking a branch/PR for test-coverage gaps, or testing React components with RTL.
74
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Write tests for Positron source code, then have them independently reviewed.
$ARGUMENTS may contain:
src/vs/.../myComponent.tsx) -- write tests for this specific file--branch <branch-name> to analyze all changes on a branch#12242 or 12242) to analyze a pull requesthttps://github.com/posit-dev/positron/pull/12242)Skip this phase if the argument is a specific source file path -- go directly to Phase 2 Prepare.
Run this phase when the argument is a branch name, PR number, or PR URL, or the user asks "what tests should I write?" without naming a file. Spawn an analysis subagent to produce a structured test plan -- this keeps the analysis work out of the main agent's context.
Agent({
description: "Analyze PR for test recommendations",
prompt: "<analysis prompt below, with arguments filled in>"
})Analyze the changes from <PR number, branch, or "current branch"> and produce a test plan for the Positron IDE.
Step 1: Get the diff.
: gh pr diff <number> --name-only and gh pr diff <number> for full content.
: git fetch origin <branch> && git diff main...origin/<branch> --name-only --diff-filter=ACMR
: git diff main...HEAD --name-only --diff-filter=ACMR
Step 2: Verify code exists on the current branch.
For each new symbol (method, class, interface member) in the diff:
grep -rq "<symbol>" <file> to confirm it exists in the working treegit log --oneline --grep="revert" -- <file> to check for post-merge revertsStep 3: Read the testing guide.
Read the Testing section of CLAUDE.md (the "Where should I put my test?" decision table), .claude/rules/vitest-tests.md for core patterns, and the JSDoc on PositronTestContainerBuilder in src/vs/test/vitest/positronTestContainer.ts for presets. For React component work, also read .claude/rules/vitest-rtl.md.
Step 4: Classify each file.
Skip: test files, type-only files, configs, docs, action-only files, files with reverted changes.
For each Positron source file in src/vs/:
createTestContainer()).tsx) with props only -> RTL prop-driven (setupRTLRenderer())usePositronReactServicesContext() -> RTL service-context (withReactServices() + setupRTLRenderer(() => ctx.reactServices)).vitest.ts or .vitest.tsx already exists.stub() calls needed beyond the presetStep 5: Return the test plan as structured output.
Format your response as:
Tests to write: For each: file path, pattern (plain/builder/RTL prop-driven/RTL service-context), preset + reasoning (why this is the lowest viable preset -- name the key dependencies that require it), extra stubs needed, what to test, whether class is exported
Tests to extend: For each: existing test file path, current preset + why it's sufficient (or what changes are needed), what new cases are needed
Already covered: Brief list
Upstream warnings: Any modified upstream files
Present the test plan to the dev. Ask: "Want me to write/extend these tests?"
Wait for confirmation before proceeding to Phase 2.
Gather the context you need before drafting the plan:
CLAUDE.md:
src/vs/test/vitest/positronTestContainer.ts for preset method names and hierarchy. Start low and let errors guide you up.Before writing any test code, present a plan and wait for explicit confirmation. This lets the dev steer scope before effort is sunk -- drop cases they don't care about, add cases you missed, reshape groupings to match how the feature is actually used.
Format the plan like this:
Plan for
<file>:Pattern:
<plain / builder / RTL prop-driven / RTL service-context><One-sentence reasoning grounded in what you observed in the source file -- e.g., "the component takes
contextMenuServiceas a prop and neither it nor its child Button usesusePositronReactServicesContext". Cite specific evidence (prop shapes, context-hook usage, service dependencies). Do not give generic reasoning like "this is a React component".>Preset:
createTestContainer()+ a preset method frompositronTestContainer.ts(see JSDoc for the current list; pick the lowest that covers your dependencies).Stubs: short list of services you intend to stub, with a one-line reason each
Test cases: (annotate tests that will use
toMatchInlineSnapshot()with[snapshot])
- <describe block 1>
- <test name 1>
- <test name 2>
[snapshot]- <describe block 2>
- <test name 3>
- <test name 4>
[snapshot]Total: tests ( snapshots). Anything you want added, dropped, or reshaped before I write?
Then stop and wait for confirmation ("looks good", "go ahead", "yes", or a revision request). Do not proceed to write tests until the dev responds.
If the dev asks for changes, revise the plan and re-present. Repeat until confirmed.
Do not skip this step, even when:
/loop or any autonomous mode -- pause anywayFor each approved item:
Write the test following the conventions in .claude/rules/vitest-tests.md (file layout, /// <reference>, assertions, builder usage, inline snapshots). For React tests, also follow .claude/rules/vitest-rtl.md. Authoring-specific quality bar:
.stub() calls, extract a helper.Run the test: npx vitest run <path-to-test-file>. Iterate on missing stubs per the "start low, let errors guide you up" pattern in the rules file's Builder section.
Type-check the file: npm run test:positron:check-ts 2>&1 | grep '<test-file-name>.vitest.ts'. This surfaces strict TypeScript errors (overload compatibility, missing properties on stubs, etc.) that npx vitest run does NOT catch — the output matches what the VS Code Problems pane shows. The file must be clean before considering it done.
Check coverage for React component tests: npx vitest run --coverage --coverage.include='**/sourceFile.tsx' <path-to-test-file>
For React tests, run npx eslint <file> before considering it done -- eslint-plugin-testing-library enforces most of the RTL conventions.
Move to the next file. Do NOT ask the dev after each file.
Don't run the full suite here -- it runs exactly once, after Phase 3 fixes land (see below). Running it now just duplicates that pass.
After all tests are written, verify builder adoption for every new test file:
grep -l "positronWorkbenchInstantiationService\|new TestInstantiationService" <new-test-files>If any new file uses manual instantiation service creation, rewrite it to use createTestContainer() before proceeding to Phase 3. This check does not apply to files that were extended (where you matched existing patterns).
After all tests pass and builder enforcement is confirmed, spawn one review subagent for all new/modified test files. Use the checklist from .claude/skills/review-vitest-tests/SKILL.md.
Agent({
description: "Review all new tests",
prompt: "Review these test files using the checklist in .claude/skills/review-vitest-tests/SKILL.md:\n\n<list each test file and its source file>"
})For each issue:
npx vitest run <path-to-test-file>After all fixes are applied, run the full suite exactly once: npm run test:positron (equivalent to npx vitest run -- pick one, don't run both). This is the only full-suite run in the whole workflow; preceding steps only ever run targeted files.
Present the dev with a summary:
b87c504
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.