describe/test/assert workflow you already use — while every run is recorded to Phoenix as a versioned experiment you can debug, compare, and share.
Available in arize-phoenix-client 2.10.0+ (Python pytest plugin) and @arizeai/phoenix-client 6.11.1+ (TypeScript Vitest/Jest, beta)
Why run evals as tests
If your team already lives in pytest or Vitest/Jest, these integrations give you that exact developer experience — fixtures, parametrization, watch mode,.only/.skip, mocks — backed by Phoenix’s observability and collaboration. The mapping is direct: each suite becomes a dataset, each case becomes a dataset example, and each run of the suite becomes an experiment.
- Debug failures in Phoenix. LLM apps are nondeterministic, which makes failures hard to chase down from a terminal alone. Every test case is traced — inputs, outputs, and the full span tree — so a failing assertion links straight to the trace that produced it. Evaluator (LLM-as-judge) calls are captured under their own evaluator span, so judge logic never clutters the task trace.
- Track metrics beyond pass/fail. Tests usually only tell you green or red. LLM quality is rarely that binary. Log any score, label, or explanation per case with
log_evaluation/logAnnotation, and Phoenix tracks it across experiments so you can watch quality trend over time instead of just blocking on a hard threshold. - Gate CI on aggregate quality. Beyond per-case asserts, define acceptance criteria that fail the suite when an aggregate metric slips — mean correctness below
0.8, fewer than 90% of runs passing, or mean latency above a budget. They run after every case, so one CI run surfaces every regression, not just the first. - Share results with your team. Building with LLMs is a team sport — subject-matter experts weigh in on prompts and rubrics. Experiments live in Phoenix, so anyone can open a run, inspect a trace, and compare against history without rerunning anything locally.
- Reuse pre-built evaluators. Hallucination, relevance, QA correctness, toxicity, and more from
arize-phoenix-evals(and@arizeai/phoenix-evals) plug directly into a test case — the same evaluator you’d pass torun_experimentworks unchanged here.
Get started with pytest
Mark a test with@pytest.mark.phoenix and log inputs, outputs, and scores with the helpers from phoenix.client.pytest. Here a text-to-SQL app is checked for both an inline LLM-as-judge score and a hard assertion.
pytest-asyncio, pytest-xdist (-n auto still creates exactly one experiment), fixtures, and parametrize. Set PHOENIX_TEST_TRACKING=0 to iterate locally without recording.
Get started with Vitest / Jest
Importdescribe/test from the @arizeai/phoenix-client/vitest (or /jest) entrypoint and add the Phoenix reporter. Suite-level acceptance criteria turn aggregate quality into a CI gate.
Testing frameworks vs. run_experiment
Phoenix already offers run_experiment (and runExperiment in TypeScript): define a dataset up front, then run one task and a shared set of evaluators across every example. That’s the right tool for large, homogeneous datasets — black-box testing where every case is scored the same way, parallelized automatically.
The test-runner integrations shine where that uniform shape gets in the way:
- Per-case evaluation logic. When you’re testing an agent with several tools, how you grade a search call and a code-execution call can be completely different. Separate test cases with their own evaluators are far more natural than one branching global evaluator.
- Real-time local feedback. Watch mode,
.only, and mocks give you a tight iteration loop while you’re developing — fix issues as you spot them, before anything syncs. - Native CI integration. Pass/fail criteria, assertion errors, and exit codes are what test runners already do. Dropping evals into an existing CI pipeline catches regressions with no new machinery.
run_experiment for broad dataset sweeps and tests for targeted, heterogeneous checks, all recording to the same Phoenix experiments.
Evals with pytest
Full how-to: markers, logging, repetitions, xdist, and CI setup.
Evals with Vitest / Jest
Full how-to: setup, evaluators, acceptance criteria, and CI setup.

