CRITICAL: This repository aims to provide excellent tooling for generating JSON test vectors that test Ethereum execution layer clients. Correctness is absolute priority. The repo prioritizes a contributor-first mindset.
./tests/: Python tests that generate JSON test vectors (fixtures) viafillcommand./src/pytest_plugins/filler/: Implementsfillcommand (test vector generation from Python source)./src/pytest_plugins/consume/: Implementsconsumecommand (test vector execution)./src/pytest_plugins/execute/: Implementsexecutecommand (live JSON-RPC testing from Python source)./src/ethereum_test_*: Core framework libraries and data structures
"Fixtures" has TWO meanings:
- Test Fixtures (JSON files) - The test vectors this framework generates
- Pytest Fixtures - Standard pytest setup/teardown (
pre,state_test, etc.)
Fill/Consume: Python Tests → fill → JSON Fixtures → consume → Client Testing
Execute: Python Tests → execute → Live JSON-RPC Testing
All commands use uv run prefix. The uv sync --all-extras command (below) automatically creates and manages a virtual environment.
uv sync --all-extras
uvx pre-commit install# Create test
uv run eest make test
# Generate fixtures (PRIMARY WORKFLOW)
uv run fill --fork=Prague path/to/test.py --clean -v -m "not slow"
# Execute against client
uv run consume direct --bin=evm fixtures/
# Framework testing
uv run pytest path/to/test.py::test_function# Check code style and errors
uv run ruff check src tests .github/scripts
# Format code
uv run ruff format src tests .github/scripts
# Fix auto-fixable issues
uv run ruff check --fix src tests .github/scripts
# Type checking
uv run mypy src tests .github/scripts
# Framework unit tests
uv run pytest -n auto
# Run specific checks (fast checks)
uvx --with=tox-uv tox -e lint,typecheck,spellcheck
# Local docs check (fast mode: these warnings can be ignored "WARNING - Doc file 'writing_tests/..."):
export FAST_DOCS=true && export GEN_TEST_DOC_VERSION="tox" && uv run mkdocs builddef test_example(pre: Alloc, state_test: StateTestFiller):
# ✅ Dynamic allocation
sender = pre.fund_eoa()
contract = pre.deploy_contract(code=Op.SSTORE(1, 1))
tx = Transaction(sender=sender, to=contract, gas_limit=5_000_000)
state_test(pre=pre, tx=tx, post={contract: Account(storage={1: 1})})pre.deploy_contract(code, **kwargs) -> Addresspre.fund_eoa(amount=None, **kwargs) -> EOApre.fund_address(address, amount)
intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator()
tx_gas_limit = intrinsic_gas_calculator(
calldata=tx_data,
contract_creation=False,
access_list=access_lists,
) + 100_000src/
├── ethereum_test_tools/ # Core framework
├── ethereum_test_types/ # Type definitions
├── ethereum_test_fixtures/ # Pydantic models for test fixtures
├── pytest_plugins/ # Plugin system
tests/ # Test cases by fork
fixtures/ # Generated test vectors (default output directory)
- ❌ Hardcoded addresses (use
prefixture) - ❌
TestAddressin new tests (usepre.fund_eoa()) - ❌ Missing
senderparameter in transactions - ❌ Missing
@pytest.mark.valid_from("Fork")markers - ❌ Manual nonce management
@pytest.mark.valid_from("Cancun")
def test_example(pre: Alloc, state_test: StateTestFiller):
if fork >= Fork.Cancun:
# Cancun-specific logic
else:
# Pre-Cancun logic@pytest.mark.parametrize("value", [0, 1, 2**256-1])
def test_with_params(value: int, pre: Alloc, state_test: StateTestFiller):uv run fill --fork=Prague --evm-dump-dir=debug_output/ --traces path/to/test.py
jq -r '.opName' debug_output/**/*.jsonl- Fill failures: Check gas limits (increase if needed, use
transaction_intrinsic_cost_calculator) - Address conflicts: Always use
prefixture for dynamic allocation - Test collection: Functions must start with
test_ - Import errors: Check dependencies in
pyproject.toml, runuv sync --all-extras
- Line length: 100 characters
- Type annotations: Required
- Import style: Explicit imports only, no
import *, no local imports. - Path handling: Use
pathlib - Code: Use idiomatic python, prioritize readability.
- Docstrings: Always include for methods and classes. For one-liners """Use one single-line docstring with quotes on same line."""
<type>(<scope>): <description>
# Types: feat, fix, docs, style, refactor, test, chore, new
# Scopes: evm, forks, tools, pytest, tests, docs, ci, consume, fill, eest
- Search:
rg "pattern" --type python(not grep) - JSON:
jq -r '.field' file.json - GitHub:
ghCLI for all operations
uv run eest make test- Create test- Implement tests using
prefixture patterns uv run fill --fork=Fork test.py --clean -v tests/path/to/module- Generate fixturesuv run ruff check --fix- Fix linting- Commit with semantic format
Critical: Always run linting and type checking. Use --clean when filling. Never use hardcoded addresses.