Skip to main content

pytest-codex

PyPI Tests Python License: MIT

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.

pytest catches pip install where uv add was required

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.

中文 · Full reference

Start with one test

python -m pip install pytest-codex

PyPI currently provides 0.1.0. Version-checked replay below is new in the upcoming 0.2.0; install this checkout with python -m pip install . to try it.

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.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-codex 0.2.0
File Size Uploaded Provenance
pytest_codex-0.2.0.tar.gz 214.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-codex 0.2.0
File Interpreter ABI Platform
pytest_codex-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 235.0 kB

Release files / pytest_codex-0.2.0.tar.gz

Download URL pytest_codex-0.2.0.tar.gz
Size 214.1 kB
Tags Source
SHA-256 checksum
How to use checksums
599938beffff2357b7edf23c78e20bdda85615ac4de1df0ce42398f678b3c9c5
BLAKE2b-256 checksum
How to use checksums
d84a3712b8e5576cc974069e0b3fdc4dc7cb588f417cecd6000f8c0c934df966
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.2.0-py3-none-any.whl

Download URL pytest_codex-0.2.0-py3-none-any.whl
Size 20.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b6bd192e7506621f11015312c846b44a8136c689257808cada4255007d7bfab9
BLAKE2b-256 checksum
How to use checksums
9490793cb3efa152a5ad16ee92c3a2181b754cbd327daa68b301d97cb74e5070
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.2.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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page