/agent/tests). They’re stored as YAML lists in tests/*.yaml, the same files jun eval runs from git. See Agent files for the format.
Write a test
Press New test. Each test is a card:string
At the top of the card, like “refund goes to a person”. Results are matched to tests by name, so keep names unique.
text
required
The customer’s first message. Add a follow-up message adds more (Then says): the AI replies to each in turn, and the last reply is what’s checked.
select
The outcome the last reply must have:
text
What a good reply does, in plain words, like “Explains Settings → Export and says it’s emailed as a CSV.” A second AI checks the reply against it, so write it plainly and specifically.
checkboxes
Actions the reply must call. Only listed when you have actions.
actions: page actions to put on the customer’s page for every turn.page: the page path the customer is on, for actions withpages.intent: run it as a chat your app opened with an intent.expect.action: the website action the reply must propose, and optionally its inputs.
Examples
The starter tests fromjun init:
tests/basics.yaml
tests/cancellation.yaml
tests/pickup.yaml
mock (or “done”) is its result for the next turn.
Save a test from a test chat
On a task’s Test tab, Save as a test turns the chat into a test: your messages, the page, and what the last reply did (its outcome, the actions it called, the widget it showed). It goes intotests/tests.yaml, or your first test file.
Run tests
Press Run tests. It tests your unsaved draft, so you can check a change before customers see it. Fix any problems in the draft first; the button is off until there are none. Results stream in as each test finishes, four at a time:- A passed / failed count at the top.
- Each card marked Passed or Failed, with “The AI replied:” and what failed, for example:
expected outcome handoff, got answerexpected a call to lookup_order (no tools called)expected the order card (no card shown)expected the page action set_pickup, got search_placescriteria not met: … (the judge's reason)
Test cases carry no browser details, so the AI has no captured errors to flag. Flags a problem for the team is mostly seen in replays of real conversations.
The judge
Criteria, and replay comparisons, are graded by a second AI call, thejudge job. It’s told to be strict and literal, and answers YES or NO with one sentence explaining why. A NO fails the test with that sentence.
Write criteria the judge can check from the reply alone: what it must say, offer, or avoid.
Replay real conversations
From the command line,jun eval also replays recent real conversations against your changes:
--sample), it takes the customer’s first message and the browser details captured with it, and answers it twice: with the live agent and with your files. Each comes back same or changed:
- A different outcome (say, answer → handoff) is changed.
- Both handing off is same.
- Otherwise the judge decides whether both replies tell the customer the same thing in substance (facts, decision, next step), ignoring wording, tone and length.
--mock-tools and --fail-on-change for CI are covered in the CLI and CI pages.
Run tests in CI
jun eval --fail-on-change on every pull request.Tasks
Test a task by chatting with it.
Instructions
Save and go live once tests pass.
CLI
jun pull, eval and push.