Prerequisites: first read
../apifox-cli/SKILL.md. If the old main entry conflicts with this skill's domain rules, the current CLI help and this skill take precedence. When single-endpoint cases are involved, read../apifox-test-case/SKILL.md; when execution/CI/report boundaries are involved, read../apifox-test-automation/SKILL.md. Environment and variable commands are subject to the current CLI help.
Specific command parameters are subject to the current CLI help. When creating and updating test scenarios, focus on step save semantics, import/reference boundaries, variable passing, complex step field risks, and run verification boundaries. When maintaining scenarios, agents should prefer import/reference commands and get --with-case-detail to read back the real structure, then perform a local update.
When to Use
- Creating or updating test scenarios.
- Designing multi-step automated flows, such as login -> create resource -> query -> assert -> clean up.
- Orchestrating multiple step types, conditional branches, loops, waits, scripts, database operations, or external programs.
- Handling pre/post operations, variable references, variable extraction, and assertion chains.
- Troubleshooting scenario step chaining failures, empty variables, incorrect step order, and abnormal frontend display after scenario creation.
When Not to Use
- Test cases under a single endpoint: switch to
apifox-test-case。 - Running only existing scenarios, suites, or CI commands: switch to
apifox-test-automation。 - Viewing reports only: use
test-reportper the current CLI help; for execution and report boundaries, refer toapifox-test-automation。 - Configuring only environments, variables, or database connections: use commands such as environment, variables, and database-connection per the current CLI help.
Core Boundaries
| Concept | CLI Resource | Description |
|---|---|---|
| Endpoint test case | test-case |
A case bound to an endpoint, suitable for single-endpoint verification |
| Test scenario | test-scenario |
Multi-step flow orchestration, supporting complex step chaining |
| Test suite | test-suite |
Scenario/case collection and regression organization |
| Environment | environment |
Provides baseUrl, variables, and service configuration |
| Test data | test-data |
Iteration data source for scenarios or cases |
Command Entry Points
Use the current CLI help to query the parameters of test-scenario .import-steps and add-ref may not appear in the top-level "available commands" list, but each supports --help, which can be used to import steps and add scenario references.
Key facts:test-scenario create only saves metadata. Even if the create payload contains steps, steps will not be saved during the create phase. The correct flow is to first create the metadata, then get --with-case-detail, then use import-steps、add-ref or test-scenario update --file to add or modify steps.
For common imports, prefer high-level commands; do not hand-write complex HTTP binding structures. Verified entry points include:
apifox test-scenario import-steps <scenarioId> --project <projectId> --source endpoint --ids <endpointIds> --sync manual
apifox test-scenario import-steps <scenarioId> --project <projectId> --source test-case --endpoint <endpointId> --ids <testCaseIds> --sync manual
apifox test-scenario import-steps <scenarioId> --project <projectId> --source test-scenario --from-scenario <sourceScenarioId> --step-ids <stepIds>
apifox test-scenario add-ref <scenarioId> --project <projectId> --scenario <sourceScenarioId>
Semantic boundaries:
import-stepsis a copy/import as the current scenario's own step.add-refadds a step that references another scenario, without copying the internal steps of the source scenario.--sync manualis the default mode, suitable for supplementing business parameters, variable references, and assertions after import.--sync autoapplies only to endpoint/test-case sources, meaning it automatically syncs with the source API definition or single-interface test case;test-scenariosources do not support auto.- The CLI is a non-interactive command and will not automatically list all resources when an ID is missing; when an endpoint, case, scenario, or step ID is missing, follow agentHints to first list/get to locate it.
Simplified creation must provide complete required parameters, but this only creates an empty scenario. Unless the user explicitly wants a placeholder scenario, "create automated test/scenario" must not stop at an empty scenario.
Standard scenario modeling process
- Clarify the business goal: what flow to verify, what the success conditions are, and how to clean up on failure.
- Confirm project, branch, and environment.
- List the involved endpoints, cases, environment variables, test data, database connections, or scripts.
- If creating a scenario on an AI branch or iteration branch, when only adjusting the scenario itself, there is no need to first pick the referenced APIs or test cases; only when modifying the referenced APIs, single-interface test cases, or the source scenario itself should you pick the required resources from the main branch or the corresponding source iteration branch to the current branch.
- If a similar scenario already exists, first
test-scenario list/getread it as a template. - Design the step diagram in natural language first, then convert it to JSON; do not guess fields while writing.
- Get the
test-scenario-createschema to create metadata. - After creation,
test-scenario get --with-case-detailread back the complete structure. - When importing existing resources, prefer
import-stepsoradd-ref, and do not directly hand-write complex binding fields. - After import,
test-scenario get --with-case-detailagain to confirm the steps were written and HTTP case/detail expands normally. - After importing an API definition or test-case, check whether params, headers, body, and script variables are only schema example values; when business values are needed, use
test-scenario update --fileto fill them in. - For fine-grained editing, get the
test-scenario-updateschema and add or modify steps based on the complete structure. cli-schema validatepasses, then update, thentest-scenario get --with-case-detailconfirm thatstepsis non-empty and the structure is correct.
test-scenario-update The schema already includes steps, pre/post processors, assertions, extracted variables, and enum value descriptions. When writing a processor for the first time, look at the schema first; do not rely on experience to guess field names, enum values, or old formats.
Step design best practices
When designing each step, clearly write:
stepName: 这一步做什么
stepType: 使用哪类步骤
input: 请求、脚本、SQL、等待条件或引用变量
output: 提取哪些变量
dependsOn: 依赖哪些上游步骤输出
assertions: 成功条件
onError: 失败后继续、停止或清理
cleanup: 是否需要后置清理
For complex flows, layering is recommended:
准备数据
鉴权/登录
主流程操作
结果查询与断言
副作用校验
清理资源
Data passing and variable references
- Before creation, list the data sources: environment variables, global variables, pre-step requests/responses, iteration data, script output.
- For passing data between steps, prioritize Apifox's native "read the run result of a pre-step", for example
{{$.1.response.body.token}}、{{$.2.response.body.data.id}}; it only takes effect in automated test scenarios and requires running the complete scenario; running a single step alone cannot retrieve the value. - When the same data needs to be referenced multiple times, reused across modules, or given a more stable name, use the extracted variable of the post-operation, then use variable references such as
{{token}}. - Random suffixes, temporary identifiers, and data generated across steps but not from responses are suitable for writing to environment variables, for example
pm.environment.set('runSuffix', suffix);。 - When using pre-step results in scripts, do not directly write
{{...}}; usepm.variables.get("$.1.response.body.token")。 - Step references depend on step ID/number. After inserting, deleting, or reordering steps, you must check in sync whether
{{$.步骤号...}}still points to the correct step. - Do not assume the response path is necessarily
body.data.id; first confirm the path based on the actual response, for example{{$.2.response.body.id}}、{{$.2.response.body.data.id}}、{{$.2.response.body.data[0].id}}。 - When generating the payload, you must keep the
{{...}}placeholder as-is, do not escape, split, or rewrite it, otherwise it cannot be replaced at runtime. - When a variable is empty, first check whether the full scenario was run, the step ID, JSONPath, response structure, step execution order, and environment selection.
- These pass between steps,
{{$.步骤号...}}andforEachrules only apply totest-scenario, do not write them into a single-interfacetest-case。
The list response can be used as forEach.parameters.array, and within the loop use the current element to reference subsequent fields:
{
"type": "forEach",
"parameters": {
"array": "{{$.1.response.body}}",
"disableOnError": false
}
}
Reference the current element in loop sub-steps:{{$.2.element.id}}. If the first element of the array is taken by default, explicitly write out the index, for example {{$.7.response.body.data[0].id}}; if the business requires a specific element, filter first, and do not assume the list order is stable.
Step content and processor structure
Apifox CLI does not automatically format scenario content; whatever string is written is what the client displays. Pre-format string fields before writing:
- Interface Body:
requestBody.data。 - Script content:
parameters.data。 - Pre/post scripts:
preProcessors[*].data、postProcessors[*].data。
Rules:
- JSON Body is still written as a string, do not write it as an object.
- For multi-line content use
\nto write it. - Pre-formatting only affects client display readability, it does not change execution semantics.
- Processors use a flat structure
{ id, type, data, defaultEnable, enable }, do not write the old-style nested{ type, config }。 - Processors are recommended to have a stable
id, especiallyassertion、extractor、customScript; lackingidmay pass validate but cause parsing exceptions in the runner or client. - When extracting global variables,
data.variableTypeuseglobals; if you need to specify the effective scope,data.shareScopeprefer to usePROJECT。TEAMis team scope, which may depend on value-added capabilities; unless the user explicitly requests team scope, do not use it by default. - Before writing, run
cli-schema validate。 - Through
import-stepssteps imported from the API definition may only have structure or schema example values; before running, you must read back and fill in params, headers, body, script variables, etc. according to the business scenario.
Example:
{
"requestBody": {
"type": "application/json",
"data": "{\n \"name\": \"Demo\",\n \"description\": \"Readable in client\"\n}"
},
"postProcessors": [
{
"id": "postProcessors.0.customScript",
"type": "customScript",
"data": "pm.test('返回 ID', function () {\n var body = pm.response.json();\n pm.expect(body.data.id).to.exist;\n});",
"defaultEnable": true,
"enable": true
},
{
"id": "postProcessors.1.extractor",
"type": "extractor",
"data": {
"variableName": "project_pet_name",
"variableType": "globals",
"shareScope": "PROJECT",
"subject": "responseJson",
"expression": "$.name"
},
"defaultEnable": true,
"enable": true
}
]
}
Assertion and script rules
For regular validation, prefer visual assertion, and use custom scripts only as a fallback capability.
Assertion rules:
- When referencing an interface to form an HTTP step, prefer to use the original interface's built-in contract test/response validation; the default contract usually already covers the success status code, for example 200.
- When the interface contract test is enabled, do not repeatedly add synonymous assertions such as "HTTP status code is 200"; only add business assertions outside the contract.
- Only when there is no suitable contract validation, or when additional business fields need to be verified, add separately
assertion。 - For regular validation such as HTTP status code, JSON field existence/equality, text contains, prefer visual
assertion, do not write by defaultcustomScript。 - Visual assertion fields use the current schema enum: for HTTP status code use
httpCode, do not useresponseCode; for JSON fields useresponseJson, do not useresponseBody; The full text containsresponseText+include; comparison operators useequal, do not useequals。
{
"type": "assertion",
"data": {
"name": "返回 ID",
"subject": "responseJson",
"comparison": "exists",
"path": "$.data.id",
"value": ""
},
"defaultEnable": true,
"enable": true
}
Script rules:
- Custom scripts are only used for logic that cannot be covered by visual assertions, such as complex array filtering, conditional judgment, secondary requests, XML conversion, or schema validation.
- The Apifox script runtime reads and writes variables, accesses responses, and defines assertions through the
pmobject; script assertions usepm.test(...)wrapping. - Do not call
pm.testoutside ofpm.response.json(), to avoid errors caused by empty responses or non-JSON responses being difficult to locate. - Do not extend runtime context fields based on experience.
pm.environment.set("variable_key", "variable_value");
pm.variables.set("variable_key", "variable_value");
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("JSON value equals expected", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
Pre/post and cleanup rules
- Pre-operations are suitable for authentication, preparing data, generating random values, and initializing database state.
- Post-operations are suitable for cleaning up test data, undoing side effects, and releasing resources.
- Scenarios with side effects must consider cleanup steps to avoid polluting the environment.
- Database, external programs, and write-type API steps are high-risk operations; before execution, confirm the environment is not production.
Common complex step handling
| Step type | Modeling suggestion |
|---|---|
| API request step | First confirm the endpoint/case or direct request structure, and output key response fields |
| Conditional branch | The conditional expression must be based on existing variables or response fields |
| Loop/iteration | Clarify the maximum count, exit condition, and failure strategy |
| Wait/poll | Clarify the wait upper limit to avoid infinite waiting |
| Script step | Input and output variables should be explicit, avoiding implicit global side effects |
| Database step | First confirm the connection; SQL should only operate on test data, and sensitive information should not be output |
| Cleanup step | Even if the main flow fails, cleanup should be executed as much as possible |
Field risk reminders
- For step order, see
number, do not only look at the read-back array order. - HTTP steps must carry correct API binding information to avoid becoming isolated requests or client display exceptions. You can use
type: "http"+bindId: <endpointId>+bindType: "API"+syncMode: "SYNC_WITH_API"+httpApiCase.apiDetailIdto import APIs; the backend will generaterelatedId。 - For common endpoint/test-case/test-scenario imports, do not manually write the above complex binding structures; prefer
test-scenario import-steps; to reference other scenarios, prefertest-scenario add-ref。 - Complex business scenarios usually require
syncMode: "MANUAL"to carry custom parameters, variable references, and assertions; merely binding an API does not equal a usable business scenario. - Container step
group/if/else/loop/forEach/onErrormust containdisable=false、parameters、isOpen=true、children=[]。 - Child steps are placed in
children, do not flatten them. groupThe display name is written inparameters.name, not the top-levelname。ifand conditionbreakuseparameters.keyVariable+operator+valueVariable, do not writeexpression。elseandonErrorofparametersshould be an empty object{}。loopusesparameters.count, nottimesor other fields.delayusesparameters.timeout, unit is milliseconds, notduration。scriptsteps useparameters.type="customScript"、parameters.data=<JS code>、enable=true, do not writelanguage/code。customHttpthe URL field is calledcustomHttpRequest.path, noturl, and complete request fields are required.testCaseRefThe field isrelatedId, notcaseId。relatedIdis the HTTP case ID generated by the backend for the scenario step; do not copy and reuse it from old scenarios when creating new steps.test-scenario get --with-case-detailis used to confirm the step tree and the internal configuration of the HTTP case/detail, such as Body, Header, postProcessors; if the user explicitly requires verifying runnability, then perform run verification and check the report.onErrorCurrently there is a risk that CLI/schema/get succeed but client expansion and configuration display are unstable; when onError is involved, do not judge availability solely based on validate/get success; client confirmation is required.
Verification and debugging rules
cli-schema validateonly guarantees the basic JSON structure, not that the runner, client, or processor can necessarily parse it correctly.- After updating or importing, first
test-scenario get --with-case-detailconfirm that the step tree is non-empty and the structure is correct, but do not treat a successful get as runnable. - After creating, updating, or importing steps, by default read back first to confirm, do not run automatically; only when the user explicitly requests running, debugging a failure, or verifying runnability before delivery should you execute
test-scenario runand check the report. - When a run fails, look at the step details in the report to distinguish whether the failure occurred in the request, pre-script, post-script, assertion, variable reference, or environment.
- When debugging complex scenarios, do not repeatedly overwrite the same business scenario; when necessary, create a new versioned scenario to avoid mixing old steps with the new structure.
- Temporarily deleting scripts/assertions can be used to locate the problem, but do not treat "deleting functionality" as the final fix.
Non-violable rules
- Do not treat the structure of
test-casedirectly as the step structure oftest-scenario; to import a single-interface case into a scenario, prefer usingtest-scenario import-steps --source test-case --endpoint <endpointId> --ids <caseIds>。 - Do not create only an empty scenario name; it must contain a displayable, runnable step structure.
- Do not mistakenly think that create can save steps; you must create the metadata first and then use
import-steps、add-reforupdate --fileto write steps. - Do not guess complex step fields based on experience; first read the schema and existing scenario templates.
- Do not let subsequent steps reference data from an unconfirmed source; first confirm whether it comes from a step response, environment variable, iteration data, extractor, or script output.
- Do not execute steps with side effects without confirming the environment.
- Before updating a scenario, you must first
get --with-case-detailthe original structure to avoid overwriting the entire step tree. - Do not repeatedly overwrite the same complex business scenario for debugging; when necessary, create a new versioned scenario to avoid mixing old steps with the new structure.
Debugging process
| Symptom | Handling |
|---|---|
| Scenario created successfully but frontend steps are not displayed | test-scenario get to see the actual saved structure, and if necessary convert to apifox-cli-checkup |
| Subsequent step variables are empty | Check the upstream extractor, response path, variable name, and execution order |
| Scenario run fails but the single interface succeeds | Check variable passing between steps, environment, pre-scripts, and dependency order |
| Loop or wait is stuck | Check the exit condition, maximum count, timeout |
| Cleanup was not executed | Check the failure strategy and post-step configuration |
| The report has no step details | First follow apifox-test-automation to distinguish local/cloud reports, and if necessary convert to apifox-cli-checkup |