automated-structural-testing-llm-based
Structural Testing for LLM-Based Agents
This skill enables Claude to write deep structural tests for LLM-based agents — not just end-to-end acceptance tests, but layered tests that capture agent trajectories as traces, mock LLM behavior for deterministic replay, and assert on internal tool invocations and intermediate outputs. The approach adapts the classical test automation pyramid (unit / integration / E2E) to agentic systems, enabling fast regression detection and root-cause analysis without expensive live LLM calls.
When to Use
- When the user asks to write tests for an LLM agent or agentic workflow
- When an agent has tools (function calls) and the user needs to verify correct tool selection and parameterization
- When the user wants deterministic, repeatable agent tests that don't call a live LLM
- When debugging why an agent chose the wrong tool or produced an incorrect response — root-cause analysis via trace inspection
- When the user wants to adopt TDD for agent development: define expected traces first, then implement the agent
- When building a CI pipeline for an agentic application and needing fast, cost-free regression tests
- When the user needs to test multi-turn conversation flows with specific expected tool chains
Key Technique
Traditional agent testing evaluates from the user's perspective: give it an input, check the final output. This is the top of the test pyramid — slow, expensive, and brittle. Structural testing operates at the lower layers. It captures traces — structured records of every internal operation (LLM invocations, tool calls, intermediate reasoning) — and makes them the foundation for assertions. Instead of asking "did the agent give a good answer?", you ask "did the agent call get_weather with city='Amsterdam' before composing its response?"
The method has three pillars. Traces (OpenTelemetry-compatible) record agent trajectories: which tools were invoked, with what inputs, what they returned, how many LLM turns occurred, token counts, and latency. Mocking replaces the live LLM with deterministic response sequences so that a test always follows the same execution path — no flakiness from model non-determinism. Assertions operate on the collected traces to verify structural properties: tool inclusion/exclusion, output content, invocation order, and custom validation functions.