[QA Method] Generate agent-native test cases in enriched CSV format from JIRA tickets, features, checklists, or existing suites. Uses business logic invariants and edge case library.
설치
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
[QA Method] Generate agent-native test cases in enriched CSV format from JIRA tickets, features, checklists, or existing suites. Uses business logic invariants and edge case library.
argument-hint
VCST-XXXX | domain | suite ID | migrate <suite> | from-checklist <domain>
/qa-test-cases-generator — Agent-Native Test Case Generation
Generate structured test cases in the enriched CSV format defined by test-case-template.md. Produces test cases that AI agents can execute directly via MCP browser tools — with typed steps, explicit assertions, cross-layer checks, and failure signals.
Usage
/qa-test-cases-generator VCST-4565 # Generate from JIRA ticket (auto-detects layers)
/qa-test-cases-generator cart # Generate for a domain (all layers)
/qa-test-cases-generator suite 06 # Extend existing suite with new cases
/qa-test-cases-generator migrate 04 # Migrate legacy suite to enriched format
/qa-test-cases-generator from-checklist payment # Generate from domain checklist items
/qa-test-cases-generator from-bdd "Given user has items in cart, When they apply coupon..."
# Layer-specific generation
/qa-test-cases-generator VCST-4565 --layer api # REST API tests only
/qa-test-cases-generator VCST-4565 --layer graphql # GraphQL xAPI tests only
/qa-test-cases-generator VCST-4565 --layer admin # Admin UI tests only
/qa-test-cases-generator VCST-4565 --layer e2e # E2E cross-layer flows only
/qa-test-cases-generator VCST-4565 --layer all # All layers (default for tickets)
/qa-test-cases-generator coupons --layer api,graphql # Multiple specific layers
Supporting Files
test-case-template.md — Enriched CSV column spec with step type tags, assertion predicates, cross-layer checks, failure signals. Read this first — it is the format contract.
test-case-examples.md — Concrete examples per layer (REST API, GraphQL, Admin UI, E2E). Read when you need a reference output for a specific layer.
Cross-Agent Knowledge (knowledge/)
Load these references during generation:
business-logic.md — BL-* invariant IDs to populate Business_Rule column
e-commerce-edge-cases-library.md — ECL-* IDs to populate Edge_Case_Refs column
catalog.md, store-settings.md — Product types, store config for realistic test data
platform-patterns.md — Common platform behaviors to inform assertions
Execution
Step 0: Load the Template
Read test-case-template.md from this skill folder. This defines all 15 CSV columns, type tags, assertion tags, and writing guidelines. Every generated test case MUST conform to this format.
Step 1: Determine Input Source
Argument
Source
Action
VCST-XXXX
JIRA ticket
Fetch via Atlassian MCP → extract AC, scope, affected modules
domain
Domain name
Match to domain checklist (/qa-checklist) → derive cases from items
Read legacy CSV → transform each row to enriched format
from-checklist domain
Checklist
Read domain checklist → generate 1 case per item (add a second only if the item has a distinct boundary or negative dimension with a concrete bug hypothesis)
from-bdd "Given..."
BDD scenario
Parse Given/When/Then → map to Steps/Assertions/Preconditions
Step 1.5: Determine Target Layers
If --layer is specified, use it. Otherwise, auto-detect from the feature scope:
Feature Signal
Layers to Generate
New REST endpoint or module API
api + admin (if has UI) + e2e
New GraphQL query/mutation
graphql + e2e
Admin UI feature (CRUD, blade, grid)
admin + api (for data verification)
Storefront feature (cart, checkout, catalog)
storefront (base format) + graphql + e2e
Cross-cutting feature (coupons, pricing, orders)
all layers
Bug fix
layer where the bug was found + e2e regression
Layer resolution rules:
Read JIRA ticket labels, component field, and affected modules
Check if the feature has REST endpoints → include api layer
Check if the feature has GraphQL operations → include graphql layer
Check if the feature has Admin UI → include admin layer
If the feature spans storefront + backend → include e2e layer
Default for --layer all: generate for every applicable layer
Each layer produces its own test case block with layer-appropriate tags from test-case-template.md (see "Layer-Specific Formats" section).
Step 2: Gather Context
Identify affected domain(s) — map input to one or more of the 63 domains in /qa-checklist
Load business rules — read business-logic.md, find all BL-* invariants relevant to the domain
Load edge cases — read e-commerce-edge-cases-library.md, find all ECL-* patterns for the domain
Check existing coverage — read the target suite CSV (if it exists) to avoid duplicating existing test cases
Get UI context — read knowledge/domain/sitemap.md for page URLs, product types, navigation paths
Step 2.5: GraphQL Schema Validation (Required for --layer graphql or GraphQL-related features)
MANDATORY when generating GraphQL test cases. Skipping this step produces invalid queries/mutations.
Authoring contract: new GraphQL test cases MUST follow the runner-native format consumed by scripts/graphql/graphql-runner.ts. Read knowledge/api/graphql-test-cases-runner.md before writing any GraphQL row — it defines the canonical Steps/Assertions/Cleanup grammar ([AUTH]/[GQL-OP]/[GQL-VARS]/[GQL-EXEC]/[GQL-CAPTURE]/[REST-OP]/[REST-EXEC]/[REST-CAPTURE]/[REST] + [ERRORS]/[DATA]/[NULL]/[COUNT]/[VAR]), getByPath filter syntax, @td() resolver, capture chaining, common failure modes, and an authoring checklist. Gold-standard examples: regression/suites/Backend/graphql/050i-graphql-configurations.csv (CFG-GQL-001…032).
Read schema reference — read knowledge/api/graphql-schema.md (introspected from live endpoint)
Check schema freshness — if the feature involves new/changed GraphQL operations, run npm run schema:refresh first to update the reference from live introspection
Validate every query/mutation in the test case against the schema:
Query/mutation name exists in the schema (e.g., there is NO createCart mutation)
Argument names and types match (e.g., products uses query:, not keyword:)
All mutations use command wrapper: mutation { name(command: { ...fields }) { ...return } }
Input type fields match — check InputAddItemType, InputCreateOrganizationType, etc. for valid field names (e.g., InputCreateOrganizationType has NO storeId)
Response field names match return type (e.g., CartType has flat subTotal, not totals { subTotal })
Guiding principle — quality over quantity. Every generated test case must have a clear bug hypothesis: a specific failure mode it is designed to catch. If you cannot answer "what real bug would this catch and why would it occur?", do not generate the case. Coverage numbers are vanity metrics — a suite of 10 targeted cases that each have a distinct failure hypothesis is more valuable than 50 shallow cases that repeat the same happy path with minor variations.
For each requirement/checklist item/BDD scenario:
Identify the happy path — generate 1 test case for the primary success flow. This is the baseline; do not generate variations of it.
Apply test design techniques selectively — only where there is a real risk of failure:
Boundary values: only for inputs where off-by-one or threshold errors are plausible in the implementation (e.g., quantity limits, price tier thresholds, discount caps)
Equivalence partitions: only when the system has genuinely distinct code paths per partition
State transitions: for lifecycle features (orders, quotes) where wrong-state transitions are a known failure mode
Error guessing: for known VC platform quirks (e.g., double-click submit, GraphQL HTTP 200 ≠ success)
Add negative cases — at minimum 1 per happy path: the most likely real-world failure (invalid input, expired token, missing required field, unauthorized role). Do not generate negative cases for every possible invalid input — pick the one most likely to slip through.
Add edge cases — only from ECL-* patterns with documented failure history for this domain. Do not add edge cases speculatively.
Add cross-domain cases — only when the interaction point between domains is a known source of bugs (e.g., cart + coupon discount stacking, checkout + inventory reservation race).
Cull before finalizing — review the full candidate list and remove any case that: (a) duplicates the failure hypothesis of another case, (b) tests infrastructure rather than logic, or (c) would only fail if the framework itself is broken.
Step 3.5: VC-Specific State Patterns (check on every applicable feature)
When the feature contains any of the following field types, generate targeted cases for them. Each pattern has known failure modes in VC — these are not speculative.
Start date in future → entity NOT active yet (storefront/API must not apply it)
Date comparison uses server time vs client time; off-by-timezone errors
P0
Start date past, end date future → entity IS active
The normal valid state — confirm it works, used as baseline
P0
End date in past → entity expired → no longer applied
Expiry check at query time vs cached at creation time
P0
Start date = today (boundary) → entity active from today
Boundary: inclusive vs exclusive comparison (>= vs >)
P1
End date = today → entity still active today or already expired?
Boundary: end of day vs start of day; timezone offset issues
P1
Start date after end date → validation error, entity not saved
Input validation — should reject before persistence, not silently swap values
P1
No end date (open-ended) → entity active indefinitely
Null end date should not be treated as "expired at epoch"
P1
Date range valid but entity also has active=false flag → inactive wins
Flag + date range interaction: both conditions must hold
P1
Minimum cases: expired case + future start case + boundary (today) case. Skip the no-end-date case only if the UI does not expose that option.
State Transitions (lifecycle objects)
Applies to: orders, quotes, RFQs, returns, import/export jobs.
Generate cases only for transitions that have business consequences:
Valid transition: state A → state B → expected behavior/data change
Invalid transition: state A → state C (should be rejected, not silently ignored)
Side effects: does the transition trigger notifications, webhooks, index updates?
Do NOT generate a case for every possible transition — only those where rejection of an invalid transition or a missed side effect would be a real bug.
Step 3.7: Prepare test-data combinations first (data-dependent cases)
Before populating any Test_Data column, delegate combination design to
/qa-generate-data <feature> — it learns the live variant
space, builds the pairwise matrix, reuses existing fixtures, authors only the gaps, and wires one
@td()combination alias per Combo ID. This makes the source of every @td() value explicit:
the prepared combinations, not invented data. Then map one case (or case group) per Combo ID so the
matrix and the suite stay traceable. The combination matrix it returns is your input to Step 4's
Test_Data column. Skip only for cases that touch no seeded entities (pure UI/copy/validation).
This composes with — does not replace — the no-hardcode rule enforced in Step 5.
Step 4: Write Each Test Case
For every test case, populate all 15 columns following the template:
ID — PREFIX-NNN format, sequential, never reuse. Prefix matches suite (e.g., SMK, CART, PAY, AUTH, API)
Title — [Subject] — [Action/Scenario] pattern, short and action-oriented
Section — Suite > Domain > Sub-area hierarchy
Priority — Critical/High/Medium/Low based on risk and business impact
Business_Rule — At least one BL-* ID (leave blank only for pure UI tests)
Edge_Case_Refs — ECL-* IDs if the case covers a known edge case pattern
Preconditions — Human-readable state requirements, use {{VAR}} for env values. Express as state, never as "after running " (ISTQB independence rule). If setup duplicates another case's first ≥70% of steps, use Preconditions: state from <ID> (state summary) instead of restating the flow (avoid-repetition rule).
Test_Data — Only key={{VAR}} bindings, comma-separated
Steps — Every step tagged: [NAV], [ACT], [WAIT], [SCROLL], [KEY]. One action per line. WAIT after every state-changing ACT
Assertions — Tagged: [DOM], [STATE], [MATH], [FORMAT], [NAV]. Explicit predicates, no vague language
Cross_Layer_Checks — Tagged: [API], [CONSOLE], [NETWORK], [ADMIN], [EMAIL]. Every mutation MUST check errors[] is empty
Failure_Signals — At least 2: one timeout signal + one API/console signal
Cleanup — State restoration or none
References — REQUIRED for Critical/High: JIRA ticket (VCST-XXXX), REQ-* ID, or user-story link. BL-* IDs alone do NOT satisfy this — those belong in Business_Rule. Infrastructure/smoke cases use smoke-baseline placeholder (never empty).
Automation_Status — Draft for just-generated cases (default out of this skill). Promote to Reviewed only after /qa-review-tests returns ≥ PASS WITH WARNINGS AND a human/qa-lead-orchestrator approves. Automated/Manual/Semi-Automated = execution mode (implies Reviewed).
Step 4.5: Provenance tagging (ground every assertion)
Generation is offline, so you tag by best-available source. For each assertion line, append a
{...} provenance tag (grammar in test-case-template.md → Assertions column):
{SPEC} — the expected behavior is stated in the tracker ticket's requirement/AC (Jira or
Azure Boards). This is the workhorse for a new feature.
{BL} — it restates a real BL-*/BL-UI-* invariant from business-logic.md.
{DOC} — you confirmed it in VirtoOZ docs or product source (/vc-docs,
PlatformFrontendSourceCode, an i18n file). Only tag {DOC} if you actually looked it up.
{HYPOTHESIS} — none of the above; it is an educated guess of a plausible bug. Phrase it as a
question ("verify whether…"), never as a fact. Do NOT invent literal message strings on these lines
(assert the semantic — literal-text rule).
Do not emit {OBSERVED} during generation — that class is reserved for the live --verify pass,
which is the only step that may confirm a behavior against the deployed build. New-feature path:
offline you will have mostly {SPEC} + {HYPOTHESIS}; those must be live-verified (upgraded to
{OBSERVED}) by a mandatory --verify run before the suite can be promoted past Draft.
Step 5: Validate & Output
Self-review each case against the writing guidelines in test-case-template.md:
Every assertion carries a provenance tag ({SPEC}/{BL}/{DOC}/{HYPOTHESIS}); no untagged
lines. No literal message/validation strings on {HYPOTHESIS} or unconfirmed {SPEC} lines —
assert the semantic (literal-text rule, DV-016 twin)
No assertions mixed into Steps
No hardcoded URLs/emails/passwords (all {{VAR}}); no hardcoded entity-specific values — IDs, SKUs, prices, addresses, coupons, test cards, order numbers — all resolved via @td(ALIAS.field) against test-data/aliases.json (see ../testing/qa-postman/test-data-fixtures.md)
Every mutation has errors[] check in Cross_Layer_Checks
At least 2 failure signals per case
Layer-correct tags: API cases use [HTTP]/[STATUS]/[BODY], not [NAV]/[ACT]
GraphQL cases always include [ERRORS] errors[] is empty assertion
GraphQL cases validated against graphql-schema.md: query/mutation names, arg names, command wrapper, response field names, MoneyType structure (Step 2.5 checklist)
Admin cases use [BLADE]/[GRID]/[SAVE] tags, not generic [ACT] for blade interactions
E2E cases have --- LAYER --- markers and assertions from ≥2 layers
Check for duplicates against existing suite cases
Output format — present as a Feature Test Matrix grouped by layer:
## Feature Test Matrix: [Feature Name] (VCST-XXXX)
### Layer: REST API (N cases → Suite 14)
| ID | Title | Priority | Business Rules | Technique |
[CSV block for API cases]
### Layer: GraphQL xAPI (N cases → Suite 15)
| ID | Title | Priority | Business Rules | Technique |
[CSV block for GraphQL cases]
### Layer: Admin UI (N cases → Suite NN)
| ID | Title | Priority | Business Rules | Technique |
[CSV block for Admin cases]
### Layer: E2E Cross-Layer (N cases → Suite 00/NN)
| ID | Title | Priority | Business Rules | Technique |
[CSV block for E2E cases]
### Coverage Summary
| Layer | P0 | P1 | P2 | Total | BL-* Coverage |
| Traceability: VCST-XXXX → [all generated case IDs]
Suggest placement — which suite file each layer's cases should be added to
Cross-layer traceability — every case in every layer links back to the same feature (VCST-XXXX in References column). The Feature Test Matrix header connects them all.
Modes
Generate Mode (default)
Produce new test cases and present them for review. Do not modify suite files without explicit confirmation.
Migrate Mode (migrate NN)
Transform legacy TestRail-format CSV rows to the enriched format:
Read the existing suite CSV
For each row, apply the migration mapping from test-case-template.md (Migration section)
Split Steps → Steps + Assertions
Split Expected Result → Assertions + Cross_Layer_Checks
Split Preconditions → Preconditions + Test_Data
Add new columns: Business_Rule, Edge_Case_Refs, Failure_Signals, Cleanup
Remove: Type, Estimate
Present the migrated CSV for review
Extend Mode (suite NN)
Read existing suite, analyze gaps, generate cases to fill them:
Read the current suite CSV and count cases per section
Cross-reference with the domain checklist(s) for that suite
Identify uncovered checklist items or missing edge cases
Generate new cases only for the gaps
Use the next available ID in the suite's numbering sequence
Output Example
PAY-042,"CyberSource — Expired Card Rejection","Payment > CyberSource > Validation",High,BL-PAY-001,"ECL-1.1, ECL-1.3","User logged in, cart has items, CyberSource payment selected on cart page","email={{USER_EMAIL}}, password={{USER_PASSWORD}}, front_url={{FRONT_URL}}","[NAV] {{FRONT_URL}}/cart
[WAIT] cart loaded with items
[WAIT] CyberSource payment form iframe visible
[ACT] fill card number: 4111111111111111
[ACT] fill expiry: 01/23
[ACT] fill CVV: 123
[ACT] click 'Place Order'
[WAIT] form validation response","[DOM] error message displayed indicating expired card
[DOM] 'Place Order' button re-enabled after error
[STATE] order NOT created — cart still intact","[API] payment authorization returns decline code
[CONSOLE] no unhandled JS errors
[NETWORK] no 5xx responses from payment gateway","Payment spinner visible >10s, 5xx from payment endpoint, console TypeError, blank payment form","none — order was not placed",VCST-4648,Automated
Layer → Agent Delegation
Generated test cases route to the correct executing agent by layer:
Layer
Execute With
Browser
Suite Target
REST API
qa-backend-expert
playwright-edge or Postman MCP
Backend/api/049-*.csv
GraphQL xAPI
qa-backend-expert
playwright-edge or Postman MCP
Backend/graphql/050*.csv
Admin UI
qa-backend-expert
playwright-edge or Chrome DevTools
Backend/<module>/*.csv (by module)
Storefront UI
qa-frontend-expert
playwright-chrome
Frontend/<area>/*.csv (by area)
E2E Cross-Layer
qa-frontend-expert + qa-backend-expert
coordinated
Suite 00 or feature suite
Storybook/A11y
ui-ux-expert
Chrome DevTools
Separate
Integration with Other Skills
Skill
Relationship
/qa-checklist
Checklists are input — each item becomes 1-3 test cases
/qa-test-design
Techniques (EP, BVA, decision tables) drive case derivation
/qa-generate-data
Prepare data first (Step 3.7) — designs the cross-entity combinations + @td() combination aliases each data-dependent case references; map ≥1 case per Combo ID
/qa-risk
Risk level determines priority assignment and case count
/qa-coverage-gap
Gap analysis identifies where new cases are needed most
/qa-plan
Generated cases feed into test plans
knowledge/domain/sitemap.md
Sitemap provides URLs and navigation context for steps
/qa-api ref
xAPI reference for Cross_Layer_Checks assertions
../testing/qa-postman/test-data-fixtures.md
@td(ALIAS.field) resolver, test-data/aliases.json registry, fixture conventions — read before populating Test_Data or Preconditions columns with any entity-specific value
knowledge/api/graphql-test-cases-runner.md
Runner-native CSV authoring contract — read before writing any GraphQL test case (Step 2.5 enforces this)
knowledge/api/graphql-schema.md
Live introspection snapshot — verify every query/mutation name and field against this (Step 2.5 enforces this)
Rules
Ground before you assert — every assertion carries a provenance tag; anything not traceable to {SPEC}/{BL}/{DOC} is a {HYPOTHESIS} phrased as a question, and no {HYPOTHESIS}/untagged case reaches Reviewed. For a new feature (no doc/source), the mandatory --verify live pass upgrades hypotheses to {OBSERVED}. Never invent literal message strings — assert the semantic (literal-text rule).
Bug hypothesis first — every case must answer: "what real bug does this catch?" If you cannot answer, do not generate the case. Coverage numbers are vanity metrics.
Minimum effective set — a smaller suite of targeted cases is better than a large suite of shallow ones. Prefer 5 focused cases over 20 that repeat the same failure mode.
Suite sizing & packing (one suite = one runnable unit) — pack cases so each CSV is a single feature/module area that one isolated agent reads and runs in one session (/qa-regression dispatches exactly one QA-expert agent per CSV, batched 3 at a time — the browser pool):
Target ~20–40 cases per CSV (repo median is 28). ≤20 is fine for a small feature; treat >40 as a signal to split, not a target to fill.
Split by feature with a suffix, never by growing one file: 040a/040b/040c (payment processors), 050b1–050b5 (xCart), 072/072b/072c/072d (configurable products). Each split suite stays scoped to one runner.
Cap expensive browser-driven suites at ≤8 cases — long runner sessions (>2h) produce unreliable results; a suite must finish inside its CI turn/time budget (MAX_TURNS default 100, ~10 min per suite).
Never pad to hit a number — cull duplicates first (Step 3 §6), then split only when the legitimate case count outgrows one session. Smoke aggregators (042/078) are deliberate exceptions.
Counts live only in config/test-suites.json (testCount per suite) — never restate them in the CSV, the suites README, or here. Regenerate/verify with npm run suites:sync / npm run suites:lint.
Format is non-negotiable — every case MUST use all 15 columns from test-case-template.md
No vague assertions — "page loads correctly" is not an assertion. Use [DOM] product title visible or [NAV] URL matches /product/*
No compound steps — one action per [ACT] line. Wrong: click Add to Cart and verify badge. Right: separate [ACT] and [ASSERT]. This rule still applies inside journey cases — each action is one [ACT]; the journey is built from many sequential [ACT]/[ASSERT] rounds, not from compound lines
Frontend journeys are exceptions to atomicity — for Storefront UI flows where behavior depends on cross-screen state (checkout, cart→order, login+purchase, BOPIS end-to-end, address/org switch mid-journey), write one journey case with --- SCREEN: <name> --- dividers in Steps, [JOURNEY] tag in Section, and an [ASSERT] at every screen boundary. Do NOT shard into atomic per-screen cases. See agents/test-management-specialist.md → Frontend Journey Exception for full criteria
Always resolve test data, never hardcode — URLs and credentials use {{VAR}} (env-backed). Entity-specific values — IDs, SKUs, prices, emails, addresses, coupon codes, test-card numbers, order numbers, virtual-catalog roots, URL path segments — use @td(ALIAS.field) resolved against test-data/aliases.json. Hardcoded fixtures rot when catalogs are reseeded or orgs are recreated. See ../testing/qa-postman/test-data-fixtures.md for the full resolver contract and patterns. Validate with npx tsx scripts/test-data/validate-td-refs.ts
Every mutation → errors[] check — GraphQL HTTP 200 does not mean success in xAPI
Minimum 2 failure signals per case (timeout + API/console)
Negative cases are mandatory — for every happy path, generate at least one negative/error case — pick the failure mode most likely to slip through, not all possible invalid inputs
Per-feature P+N+B mix (ISTQB) — any feature group with ≥3 cases MUST include at least 1 positive + 1 negative + 1 boundary case (boundary waived only if the feature has no ordered/numeric input). Verified by /qa-review-tests Dimension 9 (TC-001)
Cases must be independent (ISTQB) — Preconditions express required state, never "after running ". Order-dependence between cases is forbidden; use state from <ID> to reference an earlier case's end-state by its described state, not by its execution
Avoid repetition by reference — if two cases share ≥70% of setup steps, the later case uses Preconditions: state from <ID> (summary) and Steps: starts from the point of divergence. Do NOT restate login/navigate/add-to-cart flows across cases in the same suite
Requirement traceability is mandatory for Critical/High — References column MUST contain a JIRA ticket or REQ-* ID for any Critical/High case. BL-* alone is not traceability — it is business-rule mapping
Cases leave this skill as Draft — peer review via /qa-review-tests + human approval promotes to Reviewed. Only Reviewed+ cases enter regression selections
ID stability — never reuse or renumber IDs. Deleted cases leave gaps in numbering
Ask before writing — present generated cases for review before appending to any suite CSV file
Append via the safe writer, never hand-rolled — once approved, append with
npm run suites:append -- <target-suite.csv> --rows <new-rows.csv> (scripts/test-cases/append-test-cases-to-suite.ts).
It validates the 15-column schema, escapes commas/newlines in Steps/Assertions, guarantees the boundary
newline, dedup-checks by ID + Title+Section, and round-trip-verifies the append (the corruption from a
hand-rolled appendFileSync — merged 29-field rows — is what prompted this). Use --dry-run to preview.