Research Test & Visualization Skill
Description
Creates tests for research code and generates publication-quality visualizations. Requires
implemented code in src/ of an active research output directory.
This skill does not execute the main research pipeline — that is Phase 3.5's responsibility
(/research-execute). If results/ is already populated, tests and visualizations use those
artifacts. If not, tests use mocks/fixtures and visualizations use inline-computed values.
Tool selection: Claude autonomously chooses testing and visualization tools to match the
languages and ecosystems already present in src/. No specific framework is mandated.
Usage
/research-test [path/to/output/dir]
Arguments
$ARGUMENTS— Optional path to the research output directory. If not provided, uses the most recentoutputs/*/directory.
Instructions
Shared rules: Read
${CLAUDE_PLUGIN_ROOT}/shared/rules.mdbefore starting. §MCP, §Claude-Only, §Visualization apply to this skill. Inline fallback (if shared rules unavailable): Gemini models: gemini-3.1-pro-preview → gemini-2.5-pro → Claude. Codex: gpt-5.4. scienceplots['science','nature'], 300dpi PNG+PDF, Nature widths (3.5/7.2in). Subagents useReadtool.
Claude-Only Mode
See §Claude-Only in shared rules.
MCP Tool Rules
See §MCP in shared rules. Additionally:
- When to search: testing best practices, benchmark references, visualization techniques, domain-specific test patterns
Common Restrictions
Regardless of tool choices, all outputs must satisfy the following contracts. These are the interface between Phase 4 and Phase 5 (Report) — violating them breaks the pipeline.
| Restriction | Requirement | Rationale |
|---|---|---|
| Plot Manifest | All visualizations must be registered in plots/plot_manifest.json using the fixed schema below | Phase 5 (Report) reads this file to assemble the report |
| Dual Format | Every plot must be saved as both PNG (300 dpi) and PDF or SVG | PNG for preview, PDF/SVG for publication |
| Execution Evidence | At least one test or verification must confirm the code runs without error | Validates implementation correctness |
| Dependency Spec | Any new test/viz dependencies must be added to the appropriate manifest (pyproject.toml, Cargo.toml, DESCRIPTION, etc.) | Reproducibility |
Step 0: Locate Implementation & Detect Workspace
-
Find the active research output directory (from
$ARGUMENTSor most recentoutputs/*/). -
Verify
src/exists and contains implementation code. -
Read
plan/research_plan.mdfor research context, test strategy guidance, and the YAML frontmatter'slanguages/ecosystemfields. -
Read all source files in
src/to understand what needs testing. -
Workspace Detection — scan for languages and ecosystems actually present:
1st signal — Package manager files (scan project root and
src/):File Ecosystem Cargo.tomlRust / cargo pyproject.toml,requirements.txt,uv.lockPython / uv or pip Project.tomlJulia DESCRIPTIONR CMakeLists.txt,MakefileC/C++ package.jsonNode.js 2nd signal — File extension distribution in
src/: Glob forsrc/**/*.rs,src/**/*.py,src/**/*.r,src/**/*.jl,src/**/*.cpp, etc. Note the count and dominant extension.Priority rule: If
research_plan.mdfrontmatter sayslanguages: ["python"]butsrc/containsCargo.tomland.rsfiles, the actual files win. Announce the discrepancy. -
Check execution results:
- Glob for
results/pre_execution_status.json. If present, parse JSON and check thestatefield. - If
pre_execution_status.jsondoes not exist butpre_execution_status.mddoes (legacy workspace), read the.mdand infer state from its content (look for SUCCESS/FAILED/PARTIAL/EXISTING). - State
SUCCESSorEXISTING→ integration tests and visualizations may useresults/data. - State
FAILED,PARTIAL, or file absent → integration tests must be skipped; use mocks/inline data.
- Glob for
Step 1: Test Strategy Discussion
-
Prepare a workspace summary:
- Detected languages and ecosystems
- Key functions/modules and their expected behaviors
- Whether
results/data is available
-
Consult Gemini for test suggestions, providing the workspace context:
mcp__gemini-cli__ask-gemini( prompt: "Given the following research implementation, suggest a comprehensive test strategy.\n\nWorkspace context:\n- Detected languages/ecosystems: {detected}\n- results/ status: {SUCCESS|FAILED|ABSENT}\n\nResearch plan:\n@{output_dir}/plan/research_plan.md\n\nSource files:\n@{output_dir}/src/*\n\nPre-execution status (if available):\n@{output_dir}/results/pre_execution_status.json\n\nSuggest tests in two tiers:\n1. Unit tests (no results/ dependency — use mocks/fixtures; must run even without pre-execution)\n2. Integration/validation tests (may depend on results/ artifacts; mark as skippable if results/ absent)\n\nRecommend appropriate testing tools for the detected languages. Do not prescribe a single framework — choose what fits the codebase.", model: "gemini-3.1-pro-preview" )If
--claude-only: Per §SubagentExec — A (CD, test strategist): Read research plan, source files, pre_execution_status. Suggest 2-tier test strategy (unit + integration) with appropriate tools for detected languages. Return structured text. -
Synthesize the test plan, keeping two tiers explicit:
- Tier 1 — Unit tests (always run):
- Individual function/module correctness
- Edge cases and boundary conditions
- Error path handling
- Use mocks/fixtures — never depend on
results/
- Tier 2 — Integration / validation tests (run only if
results/is available):- Data artifact loading and schema validation
- End-to-end result correctness against known values
- Marked skippable when
results/is absent
- Tier 1 — Unit tests (always run):
-
Present the test plan to the user for approval/modifications.
Step 2: Test Implementation
-
Choose test tooling based on detected workspace (not prescribed):
- Use the native test framework for each detected language
- For multi-language projects, run each language's tests independently and aggregate results
- Recommended defaults (use if nothing more fitting exists):
Language Test Framework Python pytestRust cargo testR testthatJulia Test.jlC/C++ ctest/Catch2
-
Write Tier 1 unit tests:
- Clear test names describing what's being tested
- Mocks/fixtures for any external data or expensive computation
- Informative assertion messages on failure
-
Write Tier 2 integration tests, guarded by availability of
results/:- Python example:
import pytest, pathlib, json _status_json = pathlib.Path("results/pre_execution_status.json") _status_md = pathlib.Path("results/pre_execution_status.md") # legacy fallback RESULTS_AVAILABLE = _status_json.exists() or _status_md.exists() @pytest.mark.skipif(not RESULTS_AVAILABLE, reason="results/ not available — run /research-execute first") def test_output_schema(): ... - For other languages, use the equivalent conditional skip mechanism.
- Python example:
-
Run all tests and report results:
- Tier 1 failures are blocking — fix before proceeding.
- Tier 2 skips (due to absent
results/) are expected and acceptable. - Tier 2 failures (results/ present but tests fail) should be investigated.
-
Fix failing Tier 1 tests or flag them for user attention if the fix requires code changes in
src/.
Step 3: Visualization
-
Create
plots/directory if it doesn't exist. -
**Choose visualiz