azclips-scenario-test-converter
Skill15 starsChanged 2 days agoMITView on GitHub
Use when converting upstream Azure CLI or Azure PowerShell live tests into Azclips record/playback scenario tests under tests/Scenario.Tests with verified command syntax, assertion evidence, and user review approval.
In this repository13 other files it gives its agents.
- Agent/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- .azure-pipelines/AGENTS.mdAGENTS.md
- devops/scripts/AGENTS.mdAGENTS.md
- azclips-custom-code-classifierSkill
- extension-test-coverageSkill
- migrate-clips-to-extensions-codegen-llm-hybridSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
- openspec-sync-specsSkill
- openspec-verify-changeSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 7 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 9
Use this skill to translate Azure CLI or Azure PowerShell live tests into Azclips record/playback scenario tests.
- Very specific: line 24
Only now read the upstream tests, resolved from the Upstream Repository Map in .github/agents/integrate-custom-code.agent.md, and map every …
- Distinctive: line 25
Verify each planned assertion against an evidence source: the emitted output model, a supported read/show command, or the recorded request …
- Very specific: line 28
Write the Test cases section, and hand it on as Next Step describes.
- Distinctive: line 40
Run four checks in order, stopping at the first failure:
- Distinctive: line 57
Check 3 needs implementation evidence, not command-table evidence.
- Distinctive: line 83
Only writing is restricted.
- Very specific: line 106
Follow the shape in the Authoring a scenario section of tests/Scenario.Tests/README.md.
- Distinctive: line 112
Never invent command syntax, parameter names, model types, property paths, or api-versions.
- Distinctive: line 114
Never assert service-generated values, timestamps, etags, ordering, or generated IPs.
- Very specific: line 122
Write the expect: lines by the Conversion Rules: assert on the step's output model, the request it sent, or the error it fails with, never …
- Very specific: line 133
Place each case by Avoiding duplicate scenarios: add its assertions to an existing scenario, extend that scenario, or create a new one.
- Distinctive: line 135
Stop for user review of the scenario code with the Apply Report.
≈ “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
Azclips Scenario Test Converter
Use this skill to translate Azure CLI or Azure PowerShell live tests into Azclips record/playback scenario tests.
tests/Scenario.Tests/README.md is the authoritative guide for what a scenario test is, how record and playback are selected, the code shape to write, and how a recording is produced and scanned. Read it first. This skill does not restate it; it only covers what is specific to converting upstream live tests, and it defers to the README and the repo whenever they disagree with anything here.
The work runs in two phases. The summary, run by /integrate-scenario-test, is read-only: it writes the test cases the Coverage Rules require. /scenario-test-spec writes them into an OpenSpec change, whose apply writes the tests, stops for user review, and records only what the user approves.
Generated scenario tests must include behavior-relevant assertions. Do not produce assertion-free tests for selected custom-code behavior unless the user explicitly asks for a smoke scenario.
Mandatory Order
Scope the work from what Azclips exposes, then work from the upstream evidence inward. The command table bounds the work before any upstream file is read; the upstream cases are proposed before anything is synthesized. The summary's order is mandatory:
- Enumerate the Azclips command surface in scope: the CLI and PowerShell keys in
src/Extensions/<Module>/ExtensionIndex.cswhose processor targets that operation group, narrowed to the given actions when there are any, and the parameters each command declares. - Confirm the scenario prerequisites, and report a review gap when either is missing:
tests/Scenario.Tests/Infrastructure/ScenarioHost.csdeclares a staticExtensionUnderTestentry for the module's verb, carrying its short name, package id,ExtensionIndexassembly, CLI verb, and CLI leaves; andtests/Scenario.Tests/Scenario.Tests.csprojhas aProjectReferencetosrc/Extensions/<Module>/Extensions.<Module>.csproj. An entry whose leaves include the root leaf""routes every command under its verb, so a new command under an existing verb needs no change here. The PowerShell surface needs no cmdlet module project, becauseRunPowerShellbuilds the sameCommandInvocationa cmdlet'sProcessRecordwould build. - Determine which of those commands already have a scenario, by reading the existing scenarios under
tests/Scenario.Testsand the commands they drive throughRunCliandRunPowerShell. - Only now read the upstream tests, resolved from the
Upstream Repository Mapin.github/agents/integrate-custom-code.agent.md, and map every case onto that command table. See Coverage Rules. - Verify each planned assertion against an evidence source: the emitted output model, a supported read/show command, or the recorded request body. An assertion you cannot verify is a review gap.
- Propose the upstream-derived test cases first, applying Rule 2.
- Recompute coverage against the command table. Only the commands still uncovered after step 6 need a synthesized test case, under Rule 1.
- Write the
Test casessection, and hand it on asNext Stepdescribes.
Coverage Rules
The command table decides scope, not judgment about which upstream behavior matters. The two rules are numbered by importance; Mandatory Order sets when to apply them.
Rule 1: every command in scope needs a scenario
Every CLI and PowerShell key in scope ends with a scenario, or with a reported reason it has none for the user to accept. Scope is that part of the command table exactly: a REST operation with no key is out, and a key backed by a generated processor is in, because its command-to-REST translation is still worth pinning.
Rule 2: an upstream case whose logic exists in Azclips must be converted
Run four checks in order, stopping at the first failure:
- Command. Is it in
GetCommandTablefor either surface? - Parameters. Is every parameter the case uses in that command's
ParametersorParameterAliases? - Implementation. Is the asserted behavior reachable? A parameter can bind to a processor property that nothing reads, accepting the input and ignoring it.
- Dependencies. Can every command the case leans on — setup, intermediate state, cleanup — be driven from the table?
| Outcome | Decision |
| All four pass | convert |
| Command and behavior exist, some parameters absent | convert-partial: convert the expressible part, record the absent parameters as a review gap |
| Command and parameters exist, behavior not reachable | not-implemented: skip the assertion, and send the finding back to /custom-code-spec |
| Command absent from the table | out-of-scope |
| The case needs another command absent from the table | prerequisite-missing: skip the command under test and report it |
Confirming the behavior is implemented
Check 3 needs implementation evidence, not command-table evidence. Confirm at least one:
CreateRequestUri(),CreateRequestBody(), orCreateRequestHeaders()reads the property the parameter binds to.- A customization under
src/Extensions/<Module>/Customizationbranches on it, or passes it to a composed processor. - The asserted property exists on the output model under
src/Extensions/<Module>/Models, and the processor writes that model out.
All upstream suites, one scenario
Azure CLI, Azure CLI Extensions, and Azure PowerShell rarely cover the same cases, so enumerate every case in every suite resolved; one that appears in a single suite still converts. The suite does not decide the surface: a case asserts on both Azclips surfaces when the behavior is reachable from both GetCommandTable(CLI) and GetCommandTable(PowerShell), on one when it is reachable from one. Cases proving the same behavior become one scenario, the later ones marked duplicate-of the first.
Collapsing parameter variations
Upstream tests one command many times with different values, and different suites repeat each other. Collapse them only when the values reach the same code path. A value that selects a different branch never collapses: a different enum member, parameter set, defaulted versus explicit value, sync versus long-running path, or success versus expected failure.
Avoiding duplicate scenarios
Each recording costs a real Azure run, so take the cheapest option that still proves the behavior:
| Situation | Action | Recording cost |
| The behavior is visible in data an existing committed recording already holds | Add the assertion to that scenario | None |
| The case needs a parameter or command the existing scenario does not send | Extend that scenario, if the behavior belongs to the same lifecycle | That scenario must be re-recorded |
| The case selects a different branch, or needs setup that conflicts with the existing one | New scenario | A new recording |
Target Locations
Only writing is restricted; read anything. These three paths, and nothing else:
| Path | Allowed edit |
tests/Scenario.Tests/<Module>/<Name>ScenarioTests.cs | Create it. <Module> is the extension's module folder, such as Resources, and <Name> a PascalCase Azclips command or behavior name. |
tests/Scenario.Tests/Infrastructure/ScenarioHost.cs | Add an ExtensionUnderTest entry for a module or verb that has none, with the root leaf "" among its leaves. Never add leaves to an entry that already has the root leaf. |
tests/Scenario.Tests/Scenario.Tests.csproj | Add the ProjectReference that entry needs. |
tests/Scenario.Tests/SessionRecords/** is written by record mode only, after the recording approval in Applying A Scenario-Test Change. When playback fails, never hand-write, hand-edit, or hand-sanitise the JSON to make it pass.
For a worked example, read an existing scenario that resembles the target: tests/Scenario.Tests/Resources/GroupCreateScenarioTests.cs for a single command, and tests/Scenario.Tests/Network/VNetScenarioTests.cs for a create/read/list/delete lifecycle across both surfaces.
Inputs To Resolve
- The scope: a service module and operation group, the REST operation group the spec is named after. Its commands are the
ExtensionIndexkeys ofsrc/Extensions/<Module>whose processor targets its resource type in its request path, such asvirtualMachinesin.../providers/Microsoft.Compute/virtualMachines/{Name}. Optional actions, such asgetorlist, narrow it to the commands that perform those operations. Commands outside the scope may still be driven as setup or cleanup; they just need no coverage of their own, and an upstream case whose command under test is outside it isout-of-scope. - Azclips command names for both surfaces, such as
vm createandNew-AzVM. - The verified Azclips evidence source for each generated assertion, including command/cmdlet name, parameter name, output model type, and property path.
- Resource names, location, prerequisites, happy paths, expected failures, and cleanup behavior from the upstream live test case being converted.
Scenario tests take no subscription input. Playback resolves the placeholder subscription 00000000-0000-0000-0000-000000000000 from the stub profile, and record mode resolves the developer's signed-in subscription through host.LiveSubscriptionId().
Conversion Rules
Follow the shape in the Authoring a scenario section of tests/Scenario.Tests/README.md. These rules cover only what converting an upstream live test adds.
- Reconstruct the behavior in Azclips style; do not copy upstream test source text.
- Preserve the upstream case's resource names, location, prerequisites, ordering, expected failures, and cleanup calls, unless a value is personal, subscription-specific, or likely to collide.
- A lifecycle upstream test converts to one scenario, not several: a recording replays in recorded order.
- Drive the same commands with the same values in both the record and playback branches, and share assertion helpers, so one recording holds both surfaces to one contract.
- Never invent command syntax, parameter names, model types, property paths, or api-versions. Verify each in the repo, or report the behavior as a review gap. PowerShell names must match the
ExtensionIndexentry, which is sometimes suffixed:Get-AzVirtualNetwork_Get,Get-AzVirtualNetwork_List. - Assert on the emitted output object, not console text, typed with the extension's own models from
src/Extensions/<Module>/Models. Use a read/show command only when the result does not show the behavior. - Never assert service-generated values, timestamps, etags, ordering, or generated IPs; they change on every re-record. Never hard-code a subscription, and assert a subscription-scoped id only in playback.
Test Cases
After the Summary Report, list every proposed case in a Test cases section, upstream-derived first and synthesized after, keyed by test case ID (T1, T2). Write each block in the Input Format of .github/prompts/scenario-test-spec.prompt.md, from the command table you verified and the upstream test you read, so the next step takes the blocks as written instead of deriving them again.
- A case gets a block only when its decision is
convertorconvert-partial, or when Rule 1 synthesizes it. Theupstream_casesentry of every other case gives its reason. - Set
Surfaceby reachability, asAll upstream suites, one scenariodescribes, and give each surface its own steps, each with the expectations that check its result. - Write the
expect:lines by the Conversion Rules: assert on the step's output model, the request it sent, or the error it fails with, never on values that change on every re-record.
Next Step
Do not ask the user to choose test cases: the Coverage Rules already decide which cases become tests, so every case in the Test cases section moves on. End the summary by naming the next step, /scenario-test-spec with the whole Test cases section. eng-docs/howto/integrate-custom-code-agent.md owns the rest of the chain.
Applying A Scenario-Test Change
The tasks of a change written by /scenario-test-spec point /opsx:apply here. When the user skips OpenSpec, follow it directly with the summary's Test cases section instead.
- Write one test method per test case, following the Conversion Rules and editing only the Target Locations. Run its steps in order, and turn each
expect:line into an assertion on that step's result. Name the method after the case title, or after the behavior when the case has none, and name in a comment the case ID, and the test spec scenario it verifies when there is one. - Place each case by
Avoiding duplicate scenarios: add its assertions to an existing scenario, extend that scenario, or create a new one. - Build the test project and run it in playback mode. Playback of a new or extended scenario fails until it is recorded, which is expected; report it as
recording-requiredrather than working around it. - Stop for user review of the scenario code with the Apply Report. Apply the corrections they ask for and show the result again, repeating until they confirm.
- Only after that confirmation, ask whether to record. Record mode performs real Azure operations against the user's own subscription, so record only the scenarios the user approved, never on your own initiative, one
--filterat a time, followingRecord vs. playbackintests/Scenario.Tests/README.md. Confirm the user is signed in with the azclips CLI first. Then report the rewritten recordings for the user to review and commit, and the resources the run created that still need cleanup.
Report Format
Summary Report
Prepare command_surface and upstream_cases in the working notes before proposing test cases; they are what make Rule 1 and Rule 2 checkable. Report them at the end of the summary, followed by the Test cases section.
command_surface:
- key: "<CLI path or PowerShell invocation name>"
coverage: "existing <TestClass> | test case T<id> | uncovered: <reason>"
upstream_cases:
- id: U1
suite: "azure-cli | azure-cli-extensions | azure-powershell"
case: "<upstream test name, and the values that make this variation distinct>"
azclips_command: "<command table key, or none>"
asserted_on: ["cli", "powershell"]
implementation_evidence: "<file that reads the parameter or exposes the asserted property>"
decision: "convert | convert-partial | not-implemented | out-of-scope | prerequisite-missing | duplicate-of: U<id>"
test_case: "T<id> | none"
target: "new scenario <Class> | extend <Class>, re-record | assert on <Class>, no re-record | none"
reason: "<required unless decision is convert; name the absent parameters, the one nothing reads, or the missing command and surface>"
review_gaps:
- "<assertion that could not be verified, or prerequisite that is missing, and why>"Apply Report
Report this at the review checkpoint of the apply.
scenario_tests:
- path: "tests/Scenario.Tests/<Module>/<Name>ScenarioTests.cs"
test_methods: []
review_gaps: []
harness_changes: "<ExtensionUnderTest entry and ProjectReference added for <Module>, or none>"
coverage_result:
commands_in_scope: 0
covered_by_upstream_conversion: 0
covered_by_synthesized_scenario: 0
still_uncovered: 0
recordings:
new: []
re_record_required: []
record_filter: "<the --filter value for these scenarios>"
live_effects: "<resources the record run creates, and required cleanup>"
playback_result: "<passed | recording-required | failed with reason>"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.

