Test
Test YAML
The complete schema for test suites, file-level defaults, cases, assertions, fixtures, mocks, and approval decisions.
Last updated
YAML Format
Each file declares one or more test cases. File-level defaults apply to every case; per-case fields override them.
tests/stress-tester.yaml
version: "1.0"
# File-level defaults applied to every case.
# Per-case fields override these.
defaults:
runs: 5 # invoke the agent 5 times per case
success_threshold: 80 # 4/5 must pass for the case to pass
timeout_s: 60 # per-invocation wall clock
tests:
- name: adds_two_numbers
payload: '{"message": "add 4 and 6", "a": 4, "b": 6}'
expected_result: status == "completed"
expected_tool_calls:
- math.calculator.add: invocations >= 1
- name: plain_message_no_tools
payload: "say hello"
expected_result: status == "completed"
expected_no_tool_calls:
- math.calculator.add
- name: high_concurrency_smoke
payload: '{"message": "stress ping"}'
runs: 20 # override file default for this case
success_threshold: 95
expected_result: status == "completed"When you need more than one suite for the same agent, override the filename-derived default with the agent: field. The two files here both target stress-tester:
tests/stress-tester-load.yaml
# A second suite for the stress-tester agent. The filename can't also be
# stress-tester.yaml (it's already taken), so we point at the agent
# explicitly and give the file a more descriptive name.
agent: stress-tester
defaults:
runs: 50
success_threshold: 90
tests:
- name: sustained_burst
payload: '{"message": "stress ping"}'
expected_result: status == "completed"Field reference
| Field | Type | Status | Description |
|---|---|---|---|
| version | string | Optional | Schema version. Currently only "1.0".Default: "1.0" |
| agent | string | Optional | Agent the suite targets. Defaults to the filename stem (e.g. tests/foo.yaml → foo). Set explicitly when you want to split a large suite for one agent across multiple files. |
| defaults | object | Optional | File-level defaults applied to every case. Per-case fields override these. |
| runs | integer | Optional | How many times each case invokes the agent. Range: 1–100.Default: 1 |
| success_threshold | integer | Optional | Percent of runs that must pass for the case to pass overall. Range: 1–100.Default: 100 |
| timeout_s | integer | Optional | Per-invocation wall-clock timeout in seconds. Range: 1–3600.Default: 120 |
| mocks | string | Optional | Default custom-code replacement module for every case in the file. Per-case mocks overrides this. See Mocking Tools and Lifecycle Code. |
| strict_mocks | boolean | Optional | When true, a case fails if the agent calls an unmocked custom file tool. This check is tool-only; the three independent lifecycle strictness flags govern middleware, hooks, and custom guardrails. Per-case strict_mocks overrides this. See Mocking Tools and Lifecycle Code.Default: false |
| strict_hook_mocks | boolean | Optional | When true, a case fails before a configured eligible real hook phase executes without a matching replacement. Missing hook phases are exempt. Per-case strict_hook_mocks overrides this.Default: false |
| strict_middleware_mocks | boolean | Optional | When true, a case fails before a configured real middleware phase executes without a matching replacement. Missing middleware phases are exempt. Per-case strict_middleware_mocks overrides this.Default: false |
| strict_guardrail_mocks | boolean | Optional | When true, a case fails before a configured real custom guardrail executes without a matching replacement. Missing phases and built-in guardrails are exempt. Per-case strict_guardrail_mocks overrides this.Default: false |
| strict_approval_decisions | boolean | Optional | When true, pending approvals without a matching scripted decision and decisions left after execution fail the case. Per-case strict_approval_decisions overrides this. See Testing approvals.Default: false |
| tests | object[] | Required | Test cases. At least one required. |
| name | string | Required | Stable identifier within the file. Must be unique. Surfaces as the row title in the dashboard pipeline panel. |
| payload | string | Optional | Agent input as a string, same shape as a normal Connic payload. If the string parses as JSON it's converted before output is evaluated, so output.id == 10 works on a JSON reply. Required unless builder is set. |
| files | string[] | Optional | Bare filenames found in tests/files/. The runner reads each file, base64-encodes it, and attaches it under files. If payload is a JSON object (or comes from a builder returning a dict), its keys sit at the top level of context["payload"] next to files; otherwise the string is delivered as {message: payload}. See File Attachments.Default: [] |
| builder | string | Optional | Name of a Python module under tests/builders/ (with or without the .py suffix). Replaces the static payload with whatever call(test_details) returns. See Dynamic Payload Builders. |
| builder_args | object | Optional | Arbitrary kwargs forwarded to the builder as the builder_args argument of build() and cleanup(). Use it to vary fixtures without writing one builder per case. |
| mocks | string | Optional | Name of a Python module under tests/mocks/ (with or without the .py suffix) holding replacements for custom file tools, middleware phases, tool hooks, and custom guardrails. A matching function replaces that phase. Without one, the real code runs unless its strict mock flag is enabled. Predefined and api: tool implementations and built-in guardrails always run for real. See Mocking Tools and Lifecycle Code. |
| strict_mocks | boolean | Optional | Per-case override for defaults.strict_mocks. When true, the case fails if it calls an unmocked custom file tool. It does not govern middleware, hook, or custom guardrail replacements. |
| strict_hook_mocks | boolean | Optional | Per-case override for defaults.strict_hook_mocks. Fails before an unmatched configured eligible real hook phase executes; missing hook phases are exempt. |
| strict_middleware_mocks | boolean | Optional | Per-case override for defaults.strict_middleware_mocks. Fails before an unmatched configured real middleware phase executes; missing phases are exempt. |
| strict_guardrail_mocks | boolean | Optional | Per-case override for defaults.strict_guardrail_mocks. Fails before an unmatched configured real custom guardrail executes; missing phases and built-in guardrails are exempt. |
| approval_decisions | object[] | Optional | Scripted HITL responses. Each entry has a canonical tool, decision (approve, reject, or timeout), and optional params expression and reason. See Testing approvals.Default: [] |
| strict_approval_decisions | boolean | Optional | Per-case override for defaults.strict_approval_decisions. |
| runs | integer | Optional | Per-case override for defaults.runs. |
| success_threshold | integer | Optional | Per-case override for defaults.success_threshold. |
| timeout_s | integer | Optional | Per-case override for defaults.timeout_s. |
| expected_result | string | Optional | Expression evaluated against bindings output, error, status, context. If omitted, the case passes whenever the run reaches completed. See Assertions and expressions. |
| expected_tool_calls | list | Optional | Either bare tool names (called at least once) or one-key mappings {tool: <expr on invocations, params, and/or context>}. Mixed entries allowed in the same list, and the same tool may appear in multiple entries to lock down distinct argument sets independently.Default: [] |
| expected_tool_call_order | string[] | Optional | Tool names that must appear in this relative order in the run's tool-call trace. Other tool calls may happen between them.Default: [] |
| expected_no_tool_calls | string[] | Optional | Tool names that must NOT be called during the run. Useful for locking down the negative branch of a conditional tool selection.Default: [] |
| expected_child_agents | object | Optional | Map of triggered agent name → assertions for that child run. Each entry takes the same expected_result / expected_tool_calls / expected_tool_call_order / expected_no_tool_calls fields as the parent, plus its own nested expected_child_agents for deeper trigger chains. See Asserting on triggered agents.Default: null |
| expected_triggered | integer | Optional | (Inside an expected_child_agents entry.) Minimum number of times the named child agent must be triggered. Useful when the only thing the parent can assert is that a fire-and-forget trigger happened.Default: 1 |
| expected_payload | string | Optional | (Inside an expected_child_agents entry.) Expression evaluated against the input the parent passed to trigger_agent. Bindings: payload (JSON-parsed when the parent passed a JSON string, else the raw value), payload_raw (string form, "" when N/A), context. Works on fire-and-forget triggers too, since the payload is captured at call time. |
| expected_result | string | Optional | (Inside an expected_child_agents entry.) Same expression grammar as the top-level field, evaluated against the child run's output. Requires at least one wait_for_response=True trigger. |
| expected_tool_calls | list | Optional | (Inside an expected_child_agents entry.) Same grammar as the top-level field, evaluated against the child's tool calls.Default: [] |
| expected_tool_call_order | string[] | Optional | (Inside an expected_child_agents entry.) Tool names that must appear in this relative order in the child's tool-call trace.Default: [] |
| expected_no_tool_calls | string[] | Optional | (Inside an expected_child_agents entry.) Tools the child must NOT call.Default: [] |
| expected_child_agents | object | Optional | (Inside an expected_child_agents entry.) Recursive — assertions for agents this child triggers in turn. Stack as deep as the trigger chain goes.Default: null |