ワンクリックで
test-plan-create
// Generate a test plan from a strategy (RHAISTRAT or RHOAIENG issue), with optional ADR for extra technical depth. Use when starting test planning for a new RHOAI feature with a defined Jira strategy.
// Generate a test plan from a strategy (RHAISTRAT or RHOAIENG issue), with optional ADR for extra technical depth. Use when starting test planning for a new RHOAI feature with a defined Jira strategy.
Reviews a generated test plan for completeness, consistency, and quality using a 5-criteria rubric. Scores, auto-revises, and re-scores (max 2 cycles). Use for automated quality assessment and iterative improvement of generated test plans.
Score an existing test plan using the quality rubric without triggering auto-revision. Use for standalone quality assessment of test plans or evaluating test plans created outside the automated generation pipeline.
Generate individual test case files from an existing test plan. Use after test plan approval to generate individual TC specifications with preconditions, steps, and expected results organized by category and priority.
Browser-based UI test execution against live ODH/RHOAI clusters. Loads TCs from a GitHub PR or repo folder via ui_prepare.py, executes each via a persistent Playwright browser, and produces a visual HTML report with PASS/FAIL/BLOCKED/INCOMPLETE verdicts and screenshots. Use for verifying UI test cases against live clusters with visual evidence and screenshot capture.
Publish test plan artifacts to GitHub — creates a branch, commits all artifacts, and opens a PR with optional reviewer assignment. Use after test plan review to make artifacts available for team collaboration and formal review feedback.
Generate executable test automation code from test case specifications with intelligent placement in component or downstream repos. Use after test cases are reviewed to create production-ready pytest code that follows repository conventions.
| name | test-plan-create |
| description | Generate a test plan from a strategy (RHAISTRAT or RHOAIENG issue), with optional ADR for extra technical depth. Use when starting test planning for a new RHOAI feature with a defined Jira strategy. |
| argument-hint | <JIRA_KEY> [ADR_FILE_PATH] |
| user-invocable | true |
| model | opus |
| allowedTools | ["Read","Write","Bash","Glob","Skill","AskUserQuestion"] |
Generate a complete test plan for a RHOAI feature based on a refined strategy, and optionally an ADR document for additional technical depth.
/test-plan-create <JIRA_KEY> [ADR_FILE_PATH]
Examples:
/test-plan-create RHAISTRAT-400 (preferred - formal strategy)/test-plan-create RHOAIENG-48676 (alternative - bug/epic/task)/test-plan-create RHAISTRAT-400 /path/to/adr.pdfParse $ARGUMENTS to extract:
RHAISTRAT-400) or RHOAIENG issue (e.g., RHOAIENG-48676)If no arguments are provided and a strategy file was just generated by /strat.create or /strat.refine in this session, use it automatically — proceed directly to Step 1.
If no arguments are provided and no strategy file is available from the current session, ask the user for:
RHAISTRAT-400) or RHOAIENG issue key (e.g., RHOAIENG-48676)mcp_catalog). If not provided, derive from the feature name.Install the test-plan package (makes all scripts importable):
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv sync --extra dev)
If installation fails, inform the user and do NOT proceed. Once installed, all Python scripts will work from any directory.
Verify that Jira API credentials are configured via environment variables:
# Check for required environment variables
for var in JIRA_URL JIRA_USER JIRA_TOKEN; do
if [ -z "${!var}" ]; then
echo "Error: $var environment variable is required" >&2
echo "See CONTRIBUTING.md for Jira API setup instructions" >&2
exit 1
fi
done
If any environment variable is missing:
JIRA_URL: Base URL for the Jira instance (e.g., https://issues.redhat.com)JIRA_USER: Username or email for authenticationJIRA_TOKEN: API token for authenticationartifacts/strat-tasks/ as an alternativeIf environment variables are set, proceed to Step 0.3.
IMPORTANT: Test plan artifacts should NOT be created in the skill repository to avoid polluting the skill codebase.
Check for --output-dir flag in arguments:
FORCE_OUTPUT_DIR=trueIf no --output-dir flag, check for saved preference:
# Try to read saved preference from .claude/settings.json
saved_dir=$(jq -r '.["test-plan"]?.output_dir // empty' .claude/settings.json 2>/dev/null)
Ask user where to create artifacts via AskUserQuestion:
If saved preference exists:
Where should test plan artifacts be created?
Press Enter to use saved location:
<saved_dir>Or provide a different directory path:
If no saved preference:
Where should test plan artifacts be created?
Provide a directory path (e.g.,
~/Code/opendatahub-test-plans/plans/<team-name>), or press Enter for:~/Code/opendatahub-test-plans/plans/Note: Replace
<team-name>with your team name (e.g.,ai-hub,dashboard, etc.)
Parse user input:
~/Code/opendatahub-test-plans/plans/) or saved preference~ to home directoryValidate against skill repository (unless FORCE_OUTPUT_DIR=true):
# Validate path is not in skill repo
export CLAUDE_SKILL_DIR
force_flag=$([ "$FORCE_OUTPUT_DIR" = "true" ] && echo "--force" || echo "")
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/repo.py validate-local-path "$target_dir" $force_flag) || exit 1
Ask to save preference via AskUserQuestion (unless using --output-dir):
Save this location for future /test-plan-create runs? [yes/no]
If yes: Save to .claude/settings.json:
# Create .claude directory if it doesn't exist
mkdir -p .claude
# Update or create settings.json with output_dir preference
if [ -f .claude/settings.json ]; then
jq '.["test-plan"].output_dir = "'"$target_dir"'"' .claude/settings.json > .claude/settings.json.tmp
mv .claude/settings.json.tmp .claude/settings.json
else
echo '{"test-plan": {"output_dir": "'"$target_dir"'"}}' > .claude/settings.json
fi
echo "✓ Saved preference to .claude/settings.json"
If no: Continue without saving (will ask again next time)
Create output directory if it doesn't exist:
mkdir -p "$target_dir"
cd "$target_dir"
echo "✓ Creating test plan artifacts in: $target_dir"
Store for session context:
/test-plan-create-cases auto-detection:
export TEST_PLAN_OUTPUT_DIR="$target_dir"
/test-plan-create-cases to auto-use the same location if called in same sessionfetch_issue.py script. The strategy contains both the technical approach (HOW) and the business need (WHAT/WHY). If auto-detected, read the local file from artifacts/strat-tasks/.
# Fetch strategy and save to temporary file
strategy_file=$(mktemp)
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && \
uv run python scripts/fetch_issue.py <JIRA_KEY> --output "$strategy_file")
# Read the saved strategy
strategy_content=$(cat "$strategy_file")
# Clean up
rm "$strategy_file"
components from the Jira response by parsing the markdown output (list of RHOAI product component names, e.g., ["AI Hub", "Model Serving"])components = []Invoke these three forked analyzer skills in parallel using the Skill tool. Each runs in its own isolated context with the strategy and ADR content.
Pass the full strategy content (and ADR content if available) inline in the skill arguments so each sub-agent has the source material.
test-plan.analyze.endpoints: Extracts feature scope (in-scope, out-of-scope, test objectives) and identifies API endpoints/methods under test. Produces findings for Sections 1 and 4.test-plan.analyze.risks: Determines test levels, test types, priority definitions, risks with mitigations, and non-functional requirement assessments. Produces findings for Sections 2, 7, and 8.test-plan.analyze.infra: Identifies test environment configuration, test data, test users, infrastructure, and tooling requirements. Produces findings for Sections 3 and 9.Once all three sub-agents return:
## Gaps sections for Step 3.5mkdir -p <target_dir>/<feature_name>/test_cases
target_dir was determined in Step 0.3target_dir from Step 0.3, so: mkdir -p <feature_name>/test_cases${CLAUDE_SKILL_DIR}/test-plan-template.md using the Read tool<feature_name>/TestPlan.md by filling in the template with the gathered information. Follow the template structure exactly — do not add, remove, or reorder sections. Do NOT write frontmatter manually — Step 3.1 handles it.
<feature_name>/README.md with:
After generating TestPlan.md, set its frontmatter using the frontmatter.py script via Bash. This validates the metadata against the schema before writing.
First, auto-detect source type from Jira key prefix:
# Auto-detect source_type from Jira key
if [[ <JIRA_KEY> == RHAISTRAT-* ]]; then
SOURCE_TYPE="strat"
elif [[ <JIRA_KEY> == RHOAIENG-* ]]; then
SOURCE_TYPE="issue"
fi
Then set frontmatter:
IMPORTANT: Run Python scripts from the test-plan repo directory (where pyproject.toml is). Do NOT cd to the output directory before running scripts — use absolute paths for file arguments.
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py set <absolute_path_to_output_dir>/<feature_name>/TestPlan.md \
feature="<feature_name>" \
source_key=<JIRA_KEY> \
source_type=$SOURCE_TYPE \
version=1.0.0 \
status=Draft \
author="<team_name>" \
components="<comma-separated component names from Jira, or []>" \
additional_docs="<comma-separated list of doc links, or []>")
components: comma-separated list of component names from Jira Components field (e.g., "AI Hub,Model Serving"). Use [] if none.additional_docs: include ADR link and any other document links provided by the user. Use [] if none.last_updated is auto-set to today's date by the script.reviewers defaults to [].If the script exits with an error, fix the field values and retry — do not write frontmatter by hand.
After generating the test plan, collect all gaps reported by the three sub-agents from Step 2.
Extract gaps from each sub-agent's ## Gaps output section
Write <feature_name>/TestPlanGaps.md with all gaps organized by source sub-agent:
# Gaps — <Feature Name>
## Scope & Endpoints
{gaps from test-plan.analyze.endpoints, or "No gaps identified."}
## Test Strategy & Risks
{gaps from test-plan.analyze.risks, or "No gaps identified."}
## Environment & Infrastructure
{gaps from test-plan.analyze.infra, or "No gaps identified."}
Set frontmatter on TestPlanGaps.md using the frontmatter.py script (reuse SOURCE_TYPE from Step 3.1):
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py set <absolute_path_to_output_dir>/<feature_name>/TestPlanGaps.md \
feature="<feature_name>" \
source_key=<JIRA_KEY> \
status=Open \
gap_count=<number_of_gaps>)
gap_count: total number of individual gaps across all three sectionsstatus=Resolved and gap_count=0last_updated is auto-set by the scriptCheck for non-interactive mode:
# Auto-proceed in CI or when explicitly requested
if [ -n "${CI:-}" ] || [ -n "${CLAUDE_NON_INTERACTIVE:-}" ]; then
NON_INTERACTIVE=true
else
NON_INTERACTIVE=false
fi
If gaps exist, handle based on mode:
Non-interactive mode (NON_INTERACTIVE=true):
# Log gaps and auto-proceed to review
echo "========================================" >&2
echo "Gaps identified (auto-proceeding):" >&2
echo "========================================" >&2
cat "<feature_name>/TestPlanGaps.md" >&2
echo "========================================" >&2
# Proceed directly to Step 4 (review)
Interactive mode (NON_INTERACTIVE=false):
Present the user with a structured action menu via AskUserQuestion. List the gaps first, then offer numbered options. Example:
The following gaps were identified in the test plan:
- Endpoint paths for the catalog API are not specified — an API spec or ADR would resolve this
- RBAC roles are unclear — a feature refinement doc would help
- KServe CSI configuration details are missing — a design doc would resolve this
What would you like to do?
- Provide documents — paste file paths (ADR, API spec, design doc) to resolve gaps
- Proceed to review — continue with the test plan as-is (gaps will be noted in TestPlanGaps.md)
- Proceed to review + generate test cases — continue and automatically run
/test-plan-create-casesafter review
If the user chooses option 1: Read the provided documents, re-run only the relevant sub-agents from Step 2 with the new material, update the test plan, update TestPlanGaps.md (removing resolved gaps, adding any new ones), update the gaps frontmatter (gap_count, status), then present the menu again with remaining gaps (if any).
If the user chooses option 2, no gaps exist, or non-interactive mode: Proceed to Step 3.6.
If the user chooses option 3: Proceed to Step 3.6, and after the review is complete (Step 4), automatically invoke /test-plan-create-cases with the feature directory.
Add the test-plan-auto-created label to the source Jira issue to mark that an AI-generated test plan exists. This enables the org-pulse dashboard to track AI involvement in the test planning pipeline.
Read source_key from <feature_name>/TestPlan.md frontmatter before stamping:
source_key=$(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py read <absolute_path_to_output_dir>/<feature_name>/TestPlan.md source_key)
Then add the label using the add_jira_labels.py script:
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && \
uv run python scripts/add_jira_labels.py "$source_key" test-plan-auto-created)
Label stamping is non-blocking — if it fails (e.g., API unavailable, insufficient permissions, network error), log a warning and continue to the next step. Do not retry or halt the workflow.
After the gaps flow is complete, invoke the internal test-plan.review skill with the feature directory.
The reviewer runs the quality rubric (5 criteria, 0-2 each, 10-point scale):
The reviewer handles auto-revision internally (up to 2 cycles) and writes <feature_name>/TestPlanReview.md with scores and feedback.
Handle the review output:
Read the verdict from <feature_name>/TestPlanReview.md frontmatter
Auto-fix (if any): Apply clearly correct improvements suggested by the reviewer with these constraints:
Use the Edit tool for any auto-fixes applied.
Present summary: Show the user:
TestPlanGaps.mdIf verdict is Rework: Advise the user to provide additional source documents (ADR, API spec, design doc) to resolve quality issues before generating test cases
After reading the review verdict from TestPlanReview.md, stamp the appropriate label on the source Jira issue. This enables the org-pulse dashboard to track review outcomes.
Determine which labels to add:
test-plan-rubric-passtest-plan-rubric-failRead frontmatter values explicitly before stamping:
verdict=$(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py read <absolute_path_to_output_dir>/<feature_name>/TestPlanReview.md verdict)
auto_revised=$(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py read <absolute_path_to_output_dir>/<feature_name>/TestPlanReview.md auto_revised)
source_key=$(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && uv run python scripts/frontmatter.py read <absolute_path_to_output_dir>/<feature_name>/TestPlan.md source_key)
Build label list and apply:
# Build label list based on verdict
if [ "$verdict" = "Ready" ]; then
rubric_label="test-plan-rubric-pass"
elif [ "$verdict" = "Rework" ]; then
rubric_label="test-plan-rubric-fail"
else
echo "Warning: Unexpected verdict '$verdict', skipping rubric label" >&2
rubric_label=""
fi
# Add labels (conditionally include auto-revised)
if [ -n "$rubric_label" ]; then
if [ "$auto_revised" = "true" ]; then
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && \
uv run python scripts/add_jira_labels.py "$source_key" "$rubric_label" test-plan-auto-revised)
else
(cd $(git -C ${CLAUDE_SKILL_DIR} rev-parse --show-toplevel) && \
uv run python scripts/add_jira_labels.py "$source_key" "$rubric_label")
fi
fi
Label stamping is non-blocking — if it fails, log a warning and continue. Do not retry or halt the workflow.
/test-plan-resolve-feedback <PR_URL> after publishing)/test-plan-create-casestest-plan.analyze.risks — each category must be addressed or marked Not Applicable/test-plan-create-cases/coverage-assessment$ARGUMENTS