pytest-codex
Your AGENTS.md says “use uv.” Did Codex actually use it?
Turn agent instructions into pytest assertions. Check the commands Codex ran, the files it changed, and the MCP tools it called. Record a real run once; replay it in CI with zero model calls.
Illustration: a synthetic command trace, rendered from actual pytest failure output. No model call was used to make this image. A separate real recording is included and passes offline.
0.3.0 adds fresh task regression comparisons, available from PyPI and the GitHub release.
0.4.0 adds Codex Desktop support: import a selected historical turn without a new model call, or explicitly use the desktop-bundled engine for live/record. Imported logs are event-only observations, with no reconstructed file state or automatic history scanning.
Version 0.4.0 also includes a local rule panel:
pytest-codex-panel --project . opens a browser UI for recent project tasks,
commands, reported files, cached/uncached tokens and user-confirmed rule checks.
Launching the panel opts into bounded project-scoped history discovery, with no
model calls. Unknown evidence stays unknown, rather than green.
Start with one test
python -m pip install --upgrade pytest-codex
Version 0.4.0 includes desktop imports, the local panel and fresh task comparison reports.
Point pytest at the small project you want Codex to work on:
# pyproject.toml
[tool.pytest.ini_options]
codex_project = "sample_repo"
# tests/test_conventions.py
def test_agent_follows_project_rules(codex):
run = codex.exec("Add requests as a project dependency.")
assert run.ran("uv add", ok=True), run
assert not run.ran("pip install"), run
assert run.modified("pyproject.toml"), run
assert not run.modified("legacy/*"), run
# Record once — needs Codex CLI + login and uses model quota.
python -m pytest tests/test_conventions.py --codex-record
# Replay in CI — no Codex binary, credentials, or model calls.
python -m pytest tests/test_conventions.py
Each call gets a fresh project copy. Shell edits count as file changes too. Missing or stale recordings fail with a re-record instruction; the default mode never falls back to a paid call.
Check reliability across attempts
import pytest
@pytest.mark.codex(runs=5, pass_rate=0.8)
def test_dependency_convention(codex):
run = codex.exec("Add requests as a dependency.")
assert run.ran("uv add", ok=True), run
Record five attempts, require four to pass, and save each one separately. Replay checks those saved observations; re-record to measure a new model or CLI version.
Why a pytest plugin?
- A linter checks instruction text. This checks the commands and file changes from an execution, including edits made through shell tools.
- A one-off agent script needs its own test machinery. This fits pytest fixtures, parametrization, failure reports, and your existing CI.
- Calling a model on every PR spends quota. Checked-in recordings let ordinary PR checks replay without model calls. Use explicit live runs for fresh evidence.
Try the included recording
git clone https://github.com/Czj027/pytest-codex.git
cd pytest-codex
python -m pip install .
python -m pytest examples --codex-bin=not-installed -q
This is a real Windows recording: successful uv add, changed dependency
declarations, and untouched legacy code. The deliberately missing CLI proves
the example can replay without launching Codex.
The included recordings also cover our own project rules with two models and two attempts each, a local MCP call, and a Skill's file output. These are small smoke checks, not estimates of general model reliability. See recording evidence.
Catch stale recordings
Pin both the model and the CLI version for portable offline replay:
[tool.pytest.ini_options]
codex_model = "your-model-id"
codex_cli_version = "0.163.0"
Use --codex-check-cli locally to compare with the installed codex --version.
Version or input mismatches fail before applying recorded file changes; strict
checks require an explicit model. Default replay stays offline and needs no CLI.
An unchanged model ID cannot detect a provider updating that model; re-record
when checking current behavior.
The daily latest-CLI check uses a local canned response endpoint without login or model calls. For fresh behavior checks, use the opt-in live CI template.
Learn more
| Need | Read |
|---|---|
| Commands, files, messages, MCP calls, tokens | Run API |
| Record / replay / live / auto modes | Configuration |
| Repeat semantics and fixture sharing | Repeated runs |
| Windows setup, isolation, privacy, stale recordings | Caveats |
| Contributing and local checks | Development |
| Adding behavior tests to another project | Integration guide |
| Motivation and a worked example | Article |
run.succeeded means the CLI turn completed; use command status and file
assertions to check the work. Recordings may contain sensitive output, so review
them before committing. MIT licensed; independent community project.
Metadata
Release files for pytest-codex 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pytest_codex-0.4.0.tar.gz | 368.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_codex-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 421.0 kB
Release files / pytest_codex-0.4.0.tar.gz
| Download URL | pytest_codex-0.4.0.tar.gz |
|---|---|
| Size | 368.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
569c3aeadaed88a125cade49d5fc9029487ddc214f250924491732415c866488
|
|
BLAKE2b-256 checksum How to use checksums |
cdcaae676446ccbe9468e1166332ae421c9778b00fe11a5992758971196d75ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / pytest_codex-0.4.0-py3-none-any.whl
| Download URL | pytest_codex-0.4.0-py3-none-any.whl |
|---|---|
| Size | 52.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aa921dae0d1e51f23bcf366feec915a81d830638f3a6b264413cad3eaa22be9c
|
|
BLAKE2b-256 checksum How to use checksums |
4be6a6a2971f2211db04a2799993c3d08bfb59a446e347fa6059fef348eb07ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for pytest-codex 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.