plan-qa
Skill30 starsChanged 3 months agoMITView on GitHub
Generate QA test plan YAML from ticket
In this repository23 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- change-briefSkill
- clean-goneSkill
- close-customer-loopSkill
- commitSkill
- finishSkill
- notificationsSkill
- plan-tddSkill
- release-notesSkill
- releaseSkill
- review-requestSkill
- reviewSkill
- review-watchSkill
- rfcSkill
- setupSkill
- standupSkill
- start-qaSkill
- startSkill
- statusSkill
- syncSkill
- tddSkill
- updateSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 4 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 86
If ticket matches Linear format, use the Linear MCP server:
- Distinctive: line 103
If Jira configured, use the Jira MCP server:
- Very specific: line 120
If GitHub issue format (#123), use the gh CLI:
- Distinctive: line 132
Look for patterns in description:
- Distinctive: line 158
Create the test plan YAML:
- Very specific: line 419
Test files are saved to: {qa.testPlansDir}/{slug}-test.yaml
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Cross-runtime: follow runtime compatibility for invocation, delegation, configuration precedence, state paths, and permissions.
You are helping generate a QA test plan from a ticket description, issue tracker ticket, or requirements. This command creates a structured YAML test plan that can be executed with /start-qa.
Step 1: Load Configuration
Check for configuration:
if [ -f ".git-workflow/config.yaml" ]; then CONFIG_PATH=".git-workflow/config.yaml"; elif [ -f ".claude/config.yaml" ]; then CONFIG_PATH=".claude/config.yaml"; else CONFIG_PATH=""; fiLoad from the resolved CONFIG_PATH (canonical first, legacy read-only fallback):
qa:
apiBaseUrl: ${API_BASE_URL}
testPlansDir: tests/qa
resultsDir: tests/qa/results
timeout: 10
sqsQueueUrl: ${SQS_QUEUE_URL}
issueTracker:
type: autoDefault Values:
qa:
apiBaseUrl: http://localhost:3000
testPlansDir: tests/qa
timeout: 10Step 2: Parse Arguments
Extract from $ARGUMENTS:
$ARGUMENTSPatterns to Extract:
| Pattern | Example | Meaning |
| Ticket ID | PROJ-123, ENG-456 | Issue tracker ticket |
--url <base_url> | --url https://api.example.com | Override API base URL |
--sqs <queue_url> | --sqs https://sqs.../queue | SQS queue for events |
--sqs-env <VAR_NAME> | --sqs-env SQS_EVENTS_QUEUE | SQS queue from env var |
| Remaining text | Test the /v2/risk endpoint | Task description |
Parsing Logic:
// Extract ticket ID
const ticketMatch = args.match(/([A-Z]+-\d+)/);
const ticketId = ticketMatch ? ticketMatch[1] : null;
// Extract URL override
const urlMatch = args.match(/--url\s+(\S+)/);
const baseUrl = urlMatch ? urlMatch[1] : config.qa.apiBaseUrl;
// Extract SQS queue
const sqsMatch = args.match(/--sqs\s+(\S+)/);
const sqsEnvMatch = args.match(/--sqs-env\s+(\S+)/);
const sqsQueue = sqsMatch ? sqsMatch[1] : sqsEnvMatch ? `\${${sqsEnvMatch[1]}}` : null;
// Remaining is description
const description = args.replace(ticketMatch, '').replace(urlMatch, '').trim();Step 3: Fetch Ticket Details (If ID Provided)
Linear Integration (via MCP)
If ticket matches Linear format, use the Linear MCP server:
mcp__linear__get_issue(id: ticketId)Extract:
- Title
- Description
- Acceptance criteria (from comments or description)
- Labels/tags
The MCP server handles authentication automatically via OAuth.
Jira Integration (via MCP)
If Jira configured, use the Jira MCP server:
mcp__jira__get_issue(issueKey: ticketId)Extract:
- Summary (title)
- Description
- Acceptance criteria
- Labels
The MCP server handles authentication automatically.
GitHub Issues
If GitHub issue format (#123), use the gh CLI:
gh issue view ${ISSUE_NUMBER} --json title,body,labelsStep 4: Analyze Requirements
From the ticket or description, identify:
Endpoints to Test
Look for patterns in description:
GET /api/v1/usersPOST /endpoint- Path patterns:
/v1/,/v2/,/api/ - HTTP methods: GET, POST, PUT, PATCH, DELETE
Expected Behaviors
Extract from acceptance criteria:
- Success conditions
- Error scenarios
- Edge cases
- Authentication requirements
SQS Events (If Mentioned)
Look for:
- Event names (e.g., "USER_CREATED", "ORDER_PLACED")
- Queue mentions
- Async processing requirements
Step 5: Generate Test Plan
Create the test plan YAML:
# Auto-generated QA Test Plan
# Generated: {ISO_TIMESTAMP}
# Source: {TICKET_ID or "Manual description"}
name: "{DESCRIPTIVE_NAME}"
type: feature # feature | bug_fix | regression | smoke
description: |
{DESCRIPTION_FROM_TICKET_OR_INPUT}
# Base configuration
base_url: "${API_BASE_URL}" # or explicit URL
timeout: 10 # seconds
# Endpoints under test
endpoints:
- path: /api/v1/{endpoint}
method: GET
description: "{What this endpoint does}"
auth_required: true
# Test cases
test_cases:
# Happy path tests
- id: TC-001
name: "{Descriptive test name}"
type: happy_path
endpoint: /api/v1/{endpoint}
method: GET
headers:
Authorization: "Bearer ${API_TOKEN}"
Content-Type: application/json
params:
key: value
expected:
status: 200
body:
# Key assertions
success: true
priority: high
tags: [smoke, happy-path]
# Validation tests
- id: TC-002
name: "Invalid input returns 400"
type: validation
endpoint: /api/v1/{endpoint}
method: POST
body:
invalid_field: "bad_value"
expected:
status: 400
body:
error: true
priority: medium
tags: [validation]
# Authentication tests
- id: TC-003
name: "Missing auth returns 401"
type: auth
endpoint: /api/v1/{endpoint}
method: GET
# No Authorization header
expected:
status: 401
priority: high
tags: [auth, security]
# Edge cases
- id: TC-004
name: "Empty list returns empty array"
type: edge_case
endpoint: /api/v1/{endpoint}
method: GET
params:
filter: "nonexistent"
expected:
status: 200
body:
items: []
priority: low
tags: [edge-case]
# SQS assertions (if applicable)
sqs_assertions:
- name: "Event published after action"
queue_url: "${SQS_QUEUE_URL}"
trigger_test: TC-001 # Which test triggers this event
match_mode: json_field # json_field | contains | exact
expected_fields:
event_type: "EVENT_NAME"
# Additional field assertions
timeout_seconds: 30
required: true
# Acceptance criteria (from ticket)
acceptance_criteria:
- "{AC 1 from ticket}"
- "{AC 2 from ticket}"
- "{AC 3 from ticket}"
# Test environment
environment:
variables:
- API_BASE_URL
- API_TOKEN
setup_commands: []
cleanup_commands: []Step 6: Save Test File
Determine file name:
// From ticket ID (lowercase)
const slug = ticketId ? ticketId.toLowerCase() : null;
// Or from description (kebab-case)
const descSlug = description
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.slice(0, 50);
const fileName = `${slug || descSlug}-test.yaml`;Save to configured directory:
TEST_DIR=$(config.qa.testPlansDir || "tests/qa")
mkdir -p ${TEST_DIR}
# Write file
cat > "${TEST_DIR}/${FILE_NAME}" << 'EOF'
{GENERATED_YAML}
EOFStep 7: Confirm
Test plan generated: {TEST_DIR}/{FILE_NAME}
Summary:
- Endpoints: {N} endpoints identified
- Test cases: {M} test cases generated
- Happy path: {X}
- Validation: {Y}
- Auth: {Z}
- Edge cases: {W}
- SQS assertions: {K}
To run tests:
/start-qa {FILE_NAME}
To edit:
Open {TEST_DIR}/{FILE_NAME} and customize as needed.Configuration Reference
| Setting | Default | Description |
qa.apiBaseUrl | http://localhost:3000 | Default API base URL |
qa.testPlansDir | tests/qa | Directory for test plans |
qa.timeout | 10 | Default timeout (seconds) |
qa.sqsQueueUrl | - | Default SQS queue URL |
Examples
From Ticket ID
/plan-qa PROJ-123Fetches ticket from issue tracker and generates test plan.
From Ticket with SQS
/plan-qa PROJ-456 --sqs-env SQS_EVENTS_QUEUEGenerates test plan with SQS event assertions.
From Description
/plan-qa Test the new /v2/risk endpoint returns risk scores 0-100Generates test plan from description without ticket.
With Custom URL
/plan-qa PROJ-789 --url https://staging-api.example.comGenerates test plan targeting staging environment.
Test Case Templates
REST API Endpoint
- id: TC-001
name: "GET users returns paginated list"
endpoint: /api/v1/users
method: GET
params:
page: 1
limit: 10
expected:
status: 200
body:
items: [] # Array of users
pagination:
page: 1
limit: 10Create Resource
- id: TC-002
name: "POST creates new user"
endpoint: /api/v1/users
method: POST
body:
email: "test@example.com"
name: "Test User"
expected:
status: 201
body:
id: "*" # Any non-null value
email: "test@example.com"Error Handling
- id: TC-003
name: "Duplicate email returns 409"
endpoint: /api/v1/users
method: POST
body:
email: "existing@example.com"
expected:
status: 409
body:
error: "Email already exists"Output Location
Test files are saved to: {qa.testPlansDir}/{slug}-test.yaml
Where {slug} is:
- Ticket ID lowercase (e.g.,
proj-123-test.yaml) - Or kebab-case from description (e.g.,
risk-endpoint-test.yaml)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

