Anchor
Anchor for Dummies

Anchor for Dummies

This content is being translated and will be available here when ready.

Testing Your Program

Thorough testing prevents financial losses, builds user trust, and ensures your program behaves correctly under all conditions.

Test rigorously before mainnet deployment.

TypeScript Tests

TypeScript testing is the most common approach since you'll need TypeScript for your dApp client anyway. This lets you develop tests and client code simultaneously.

We covered client-side setup in detail here.

Every Anchor CLI project includes a test folder with a TypeScript file ready for testing.

TypeScript tests offer key advantages:

  • Mirror real client interactions
  • Test complex workflows and edge cases
  • Provide immediate feedback on API changes
  • Validate success and error scenarios

Run tests with:

bash
anchor test

Run on localnet by setting the cluster to localnet in your configuration. This spins up a local validator and adds 1,000 SOL to the provider wallet. If you need additional accounts with data inside of them, look at running a Local Validator

Mollusk Tests

When you need granular control over testing environments or complex program state setup, Mollusk provides the solution.

Mollusk is a Rust testing framework built specifically for Solana programs. It enables you to:

  • Test program logic in isolation without network overhead
  • Set up complex account states easily
  • Run tests faster than full integration tests
  • Mock specific blockchain conditions and edge cases

We covered Mollusk testing thoroughly here.

Create a new Anchor program with Mollusk:

bash
anchor init <name-of-the-project> --test-template mollusk

Run tests using:

bash
anchor test

LiteSVM Tests

When you need the same granular control over your program state, like Mollusk, but in Typescript LiteSVM provides the optimal solution.

LiteSVM is a lightweight testing framework that runs the Solana Virtual Machine directly in your test process. It enables you to:

  • Execute tests significantly faster than traditional frameworks like solana-program-test
  • Manipulate account states and sysvars with precision
  • Test across multiple languages: TypeScript, Rust, and Python
  • Mock complex blockchain conditions and edge cases effortlessly

LiteSVM eliminates validator overhead by embedding the VM within your tests, delivering the speed needed for rapid development cycles without sacrificing testing accuracy.

We covered LiteSVM testing thoroughly here.

You can set up your Anchor provider and use the client-side setup we saw previously with the anchor-litesvm package.

Installe the anchor-litesvm package.

bash
npm install git:https://github.com/LiteSVM/anchor-litesvm

Then change the default Anchor provider to LiteSVMProvider like this:

ts
import { fromWorkspace, LiteSVMProvider } from "anchor-litesvm";
 
test("anchor", async () => {
	const client = fromWorkspace("target/types/<program-name>.ts");
	const provider = new LiteSVMProvider(client);
	const program = new Program<Puppet>(IDL, provider);
 
    // program.methods..
})

Running a Local Validator

Mirror mainnet behavior locally using a validator that acts as your personal blockchain sandbox. This happens automatically when you set your cluster to localnet.

The local validator operates a simplified Solana ledger with native programs pre-installed. By default, it only stores test data and lacks access to existing mainnet accounts—limiting testing with established protocols.

Configuring Your Local Validator

Customize your validator in Anchor.toml under the [test] section:

 
[test]
startup_wait = 10000

The startup_wait flag delays validator startup, useful when cloning multiple accounts that increase load time.

Cloning Mainnet Accounts

Clone existing mainnet accounts and programs using [test.validator] configuration:

 
[test.validator]
url = "https://api.mainnet-beta.solana.com"

[[test.validator.clone]]
address = "7NL2qWArf2BbEBBH1vTRZCsoNqFATTddH6h8GkVvrLpG"
[[test.validator.clone]]
address = "2RaN5auQwMdg5efgCaVqpETBV8sacWGR8tkK4m9kjo5r"
[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"

The clone section copies accounts from the specified cluster. When an account links to a program managed by the "BPF upgradeable loader", Anchor automatically clones the associated program data account.

Loading Local Account Data

Load local accounts from JSON files using the account flag:

 
[[test.validator.account]]
address = "Ev8WSPQsGb4wfjybqff5eZNcS3n6HaMsBkMk9suAiuM"
filename = "some_account.json"

This approach works well for testing with pre-configured account states or specific configurations that don't exist on mainnet.

Running Surfnet

Testing Solana programs that rely on Cross-Program Invocations (CPIs) traditionally requires developers to dump accounts and programs from mainnet, like we saw in the Local Validator section.

This process works for a few accounts, but becomes completely unfeasible when testing CPIs into complex programs like Jupiter, which can depend on 40+ accounts and 8+ programs.

Surfnet serves as a drop-in replacement for solana-test-validator that enables developers to simulate programs locally using mainnet accounts fetched on-demand

To use it, just install surfpool using the official Installation Page and then run:

bash
surfpool start

You can now connect to Surfnet by targeting the local validator:

ts
import { Connection } from "@solana/web3.js";
 
const connection = new Connection("http://localhost:8899", "confirmed");

We covered Surfnet setup and usage thoroughly here.

Blueshift © 2025Commit: 6d01265