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.md before 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's languages/ecosystem fields.
- 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.toml | Rust / cargo | | pyproject.toml, requirements.txt, uv.lock | Python / uv or pip | | Project.toml | Julia | | DESCRIPTION | R | | CMakeLists.txt, Makefile | C/C++ | | package.json | Node.js |
2nd signal — File extension distribution in src/: Glob for src/**/*.rs, src/**/*.py, src/**/*.r, src/**/*.jl, src/**/*.cpp, etc. Note the count and dominant extension.
Priority rule: If research_plan.md frontmatter says languages: ["python"] but src/ contains Cargo.toml and .rs files, 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.
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
- 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 | pytest | | Rust | cargo test | | R | testthat | | Julia | Test.jl | | C/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:
```python 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.
- 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