Anchor TS Tests
anchor test is the default integration path for Anchor 0.32.1 projects: compile programs, deploy to a local validator, and run TypeScript tests against the IDL. Use it for end-to-end flows with real RPC semantics.
Recipe
Quick-reference recipe card - copy-paste ready.
anchor test
# or with existing validator:
anchor test --skip-local-validatorimport * as anchor from "@coral-xyz/anchor";
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.MyProgram as Program<MyProgram>;When to reach for this:
- Full integration tests with SPL Token CPIs.
- Testing Anchor account resolution and IDL types.
- CI validation before devnet/mainnet deploy.
- Client SDK contract tests alongside program.
Working Example
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyProgram } from "../target/types/my_program";
import { Keypair, PublicKey, SystemProgram } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID, createMint, getOrCreateAssociatedTokenAccount } from "@solana/spl-token";
import { assert } from "chai";
describe("my_program", () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.MyProgram as Program<MyProgram>;
const payer = (provider.wallet as anchor.Wallet).payer;
it("initializes vault", async () => {
const user = Keypair.generate();
await provider.connection.confirmTransaction(
await provider.connection.requestAirdrop(user.publicKey, 2e9)
);
const mint = await createMint(provider.connection, payer, payer.publicKey, null, 6);
const ata = await getOrCreateAssociatedTokenAccount(
provider.connection, payer, mint, user.publicKey
);
const [vaultPda] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), user.publicKey.toBuffer()],
program.programId
);
await program.methods
.initVault()
.accounts({
user: user.publicKey,
vault: vaultPda,
mint: mint,
userToken: ata.address,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
})
.signers([user])
.rpc();
const vault = await program.account.vault.fetch(vaultPda);
assert.ok(vault.authority.equals(user.publicKey));
});
});What this demonstrates:
- Provider reads cluster from
Anchor.toml. - SPL helpers create mint and ATA on local validator.
.rpc()sends signed transaction and awaits confirmation.
Deep Dive
How It Works
anchor testrunsanchor build, starts validator (unless skipped), deploys programs, executestests/**/*.ts.- Mocha is default runner;
chaiassertions common. - IDL generated to
target/idland types totarget/types. - Wallet in
Anchor.tomlpays deploy and test fees.
Anchor.toml Test Config
| Field | Purpose |
|---|---|
[provider] cluster | localnet / devnet URL |
[scripts] test | Custom test command |
[test] startup_wait | Validator readiness delay |
TypeScript Notes
// Match error codes from Rust #[error_code]
import { AnchorError } from "@coral-xyz/anchor";
try {
await program.methods.badIx().rpc();
} catch (e) {
const err = e as AnchorError;
console.log(err.error.errorCode.code);
}Gotchas
- Cluster mismatch -
Anchor.tomldevnet but validator localnet. Fix: Align provider URL with running cluster. - Airdrop failures - Local faucet limits. Fix: Fund payer in validator genesis or single airdrop per test.
- IDL not regenerated - Account name errors after Rust rename. Fix:
anchor buildbefore test. - Port 8899 busy - Orphan validator. Fix:
pkill solana-test-validatorin CI pre-step. - Slow CI - Full deploy each run. Fix: Add LiteSVM/Bankrun layer; reserve anchor test for integration job.
- Missing
--skip-local-validator- Double validator start fails. Fix: Document CI validator lifecycle.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Bankrun | Faster TS tests | Need full RPC features |
| LiteSVM | Rust unit tests | TS-only team |
| Surfpool fork | Mainnet DeFi state | Simple CRUD program |
FAQs
Default test runner?
Mocha via ts-mocha in Anchor template - can switch to node:test with custom script.
How do I test on devnet?
Set provider cluster to devnet and run anchor test --skip-local-validator with funded wallet.
Multiple programs?
Workspace Cargo.toml members all deploy in anchor test when configured in Anchor.toml.
How to share test fixtures?
before hooks create mints/users; commit JSON keypairs only for localnet, never mainnet keys.
Compute budget in tests?
Add compute budget instructions in transaction builder when ix approaches CU limit.
Versioned transactions?
Supported via web3.js v2 patterns - ensure client constructs v0 tx when testing ALTs.
anchor test vs cargo test?
cargo test runs Rust tests only; anchor test includes deploy + TS integration.
Flaky tests?
Usually validator state leakage - use --reset or unique keypairs per test.
CI caching?
Cache target/ and npm modules; still rebuild programs each run for correctness.
Agave 4.1.1 alignment?
Install matching solana CLI in CI so local validator matches production runtime.
Related
- Bankrun (TS) - faster TS VM
- Testing Against a Validator - validator ops
- Testing CPIs & PDAs - account setup
- Testing Basics - pyramid
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.