Skip to main content
Assertions are ordinary pytest assert statements. Deterministic ones are free and fast, so put them before any judge(...) call — pytest stops at the first failure, and a failed assertion never spends judge tokens. The kensa_trace fixture is your assertion helper for what the agent did. What it said is just the return value of case.run(...), which you check with plain Python.

Trace assertions

The kensa_trace fixture exposes the trace collected during the run.

Tool calls

kensa_trace.tools answers questions about which tools were invoked:
def test_refund(case, kensa_run, kensa_trace):
    case.run(kensa_run)

    # All listed tools were called (set membership, order-free)
    assert kensa_trace.tools.include(["lookup_customer"])

    # None of these tools were called (safety check)
    assert kensa_trace.tools.exclude(["issue_refund", "delete_account"])

    # Called in this relative order (other tools may interleave)
    assert kensa_trace.tools.order(["search_flights", "book_flight"])

    # No tool was called twice
    assert kensa_trace.tools.no_repeats()
MemberReturnsChecks
tools.nameslist[str]Tool names in call order
tools.include(names)boolEvery listed tool was called
tools.exclude(names)boolNone of the listed tools were called
tools.order(names)boolListed tools appear in this relative order
tools.no_repeats()boolNo tool was called more than once

Resource bounds

kensa_trace also reports cost, turns, and latency for budget assertions:
def test_within_budget(case, kensa_run, kensa_trace):
    case.run(kensa_run)

    assert kensa_trace.cost_usd < 0.10        # under 10 cents
    assert kensa_trace.llm_turns <= 5         # at most five model calls
    assert kensa_trace.duration_ms < 30_000   # under 30 seconds
AccessorTypeMeaning
kensa_trace.cost_usdfloatTotal trace cost in USD
kensa_trace.llm_turnsintNumber of LLM spans
kensa_trace.duration_msfloatTotal trace duration
kensa_trace.spanslistRaw collected spans, for custom checks
kensa_trace.incomplete is True when the trace could not be fully collected. Guard budget assertions on it if your harness can return early.

Output assertions

case.run(kensa_run) returns whatever your agent produced — a string, a dict, or any JSON-serializable value. Assert on it directly with plain Python; no special helper is involved.
import json
import re


def test_output_shape(case, kensa_run):
    output = case.run(kensa_run)
    text = output if isinstance(output, str) else json.dumps(output)

    # Substring (case-insensitive)
    assert "confirmation number" in text.lower()

    # Regex match
    assert re.search(r"\d{6,}", text)

    # Structured output: assert on fields directly
    assert output["status"] == "resolved"

    # Safety check
    assert "refund" not in text.lower()
Because the output is a normal Python value, pytest and the standard library cover output assertions — there is no Kensa-specific output API to learn.

Assertions gate the judge

Order matters. Deterministic assertions first, semantic judge last:
def test_refund_policy(case, kensa_run, kensa_trace):
    output = case.run(kensa_run)

    # 1. Free, deterministic — fails fast.
    assert kensa_trace.tools.include(["lookup_customer"])
    assert kensa_trace.tools.exclude(["issue_refund"])

    # 2. Only reached if the cheap checks passed.
    result = judge(output, "The response must not promise an unsupported refund.", input=case.input)
    assert result.passed, result.reasoning
If a tool assertion fails, the test fails immediately and the LLM judge never runs. See Judge for the semantic half.
Last modified on July 7, 2026