Loading Programs & Fixtures
Preload programs and deterministic account fixtures so every test run starts from the same on-chain state.
Search across all documentation pages
Preload programs and deterministic account fixtures so every test run starts from the same on-chain state.
Quick-reference recipe card - copy-paste ready.
solana-test-validator --reset \
--bpf-program <PROGRAM_ID> target/deploy/my_program.so \
--account <PUBKEY> fixture.json
anchor testWhen to reach for this:
.so binaries at fixed IDs.# 1. Export a fixture account once from devnet/mainnet
solana account <CONFIG_PUBKEY> --output json-compact > config-fixture.json
# 2. Start validator with program + fixture
PROGRAM_ID=$(solana-keygen pubkey target/deploy/my_program-keypair.json)
solana-test-validator --reset \
--bpf-program "$PROGRAM_ID" target/deploy/my_program.so \
--account <CONFIG_PUBKEY> config-fixture.json
# 3. Run tests against known state
solana config set --url http://127.0.0.1:8899
anchor test --skip-local-validatorWhat this demonstrates:
--bpf-program loads your bytecode at genesis.--account injects lamports/owner/data from exported JSON..so from solana program dump.Anchor.toml [test.validator] section.| Source | Command | Use case |
|---|---|---|
| RPC export | solana account --output json | Realistic configs |
| Hand-written JSON | editor | Minimal synthetic state |
| Test setup txs | before hooks | Dynamic but slower |
| LiteSVM set_account | Rust API | Fast unit tests |
# Anchor.toml example
# [test.validator]
# url = "https://api.mainnet-beta.solana.com"
# clone = ["<MINT>", "<ORACLE>"]solana account.declare_id! and keypair pubkey.| Alternative | Use When | Don't Use When |
|---|---|---|
--clone from mainnet | Live layout needed | Tiny config-only tests |
| On-chain setup instructions | Testing init flows | Repeated CI cost |
| LiteSVM | Pure Rust program logic | End-to-end RPC clients |
| devnet shared deploy | Team manual QA | Automated PR checks |
Common pattern: tests/fixtures/ committed to git with documented origin.
Yes under [test.validator] with clone array and url for source cluster.
Repeat --bpf-program <ID> <SO> flags on one validator command line.
Exported JSON includes lamports - ensure enough for rent when injecting manually.
Transactions can mutate state after boot - fixtures are only initial conditions.
Do not commit private user data - sanitize pubkeys and balances in shared fixtures.
Surfpool fork reduces need for manual fixtures - still useful for custom config overlays.
Match account size limits - large accounts slow startup proportionally.
Load .so at program ID; upgrade authority behaves per loader rules on localnet.
Re-run solana account --output json against known good cluster state and bump file version in commit message.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026