Examples
Program Testing
Load and test custom Solana programs with LiteSVM
Program Testing Example
Testing a custom Solana program means loading its compiled .so file into the SVM, setting up the accounts it expects, and sending instructions against it. LiteSVM handles all of this in-process — no validator needed. We recommend generating program clients with the Codama JS Renderer so you can have access to a compatible Kit Plugin.
Loading a Program
import { createClient, address, generateKeyPairSigner } from '@solana/kit';
import { litesvm } from '@solana/kit-plugin-litesvm';
import { signer } from '@solana/kit-plugin-signer';
import { myProgramPlugin } from '@my-program/sdk';
import * as fs from 'node:fs';
const mySigner = await generateKeyPairSigner();
const client = createClient()
.use(signer(mySigner))
.use(litesvm())
.use(myProgramPlugin());
// Configure for program testing
client.svm
.withSigverify(false)
.withBlockhashCheck(false)
.withSysvars()
.withBuiltins();
// Load program from .so file
const programId = address('YourProgramId111111111111111111111111111');
const soPath = '/path/to/target/deploy/my_program.so';
if (fs.existsSync(soPath)) {
client.svm.addProgramFromFile(programId, soPath);
console.log('Program loaded:', programId);
// Verify program account
const programAccount = client.svm.getAccount(programId);
if (programAccount.exists) {
console.log(' Executable:', programAccount.executable);
console.log(' Data size:', programAccount.data.length, 'bytes');
}
} else {
console.log('Program file not found:', soPath);
console.log('Build with: cargo build-sbf');
}Complete Program Test Setup
import { createClient, address, generateKeyPairSigner, lamports } from '@solana/kit';
import { litesvm } from '@solana/kit-plugin-litesvm';
import { signer } from '@solana/kit-plugin-signer';
import { myProgramPlugin } from '@my-program/sdk';
import * as fs from 'node:fs';
const mySigner = await generateKeyPairSigner();
const client = createClient()
.use(signer(mySigner))
.use(litesvm())
.use(myProgramPlugin());
client.svm
.withSigverify(false)
.withBlockhashCheck(false)
.withSysvars()
.withBuiltins()
.withPrecompiles()
.withTransactionHistory(100n);
// Load program
const programId = address('YourProgramId111111111111111111111111111');
const soPath = '/path/to/target/deploy/my_program.so';
if (fs.existsSync(soPath)) {
client.svm.addProgramFromFile(programId, soPath);
}
// Set up any required data accounts
const dataAccountAddress = address('DataAccount111111111111111111111111111');
const minBalance = client.svm.minimumBalanceForRentExemption(100n);
client.svm.setAccount({
address: dataAccountAddress,
data: new Uint8Array(100),
executable: false,
lamports: lamports(minBalance),
programAddress: programId,
space: 100n,
});
// Send the transaction
await client.myProgram.testInstruction({..}).sendTransaction();
// Verify state changes
const updatedAccount = client.myProgram.myAccount.fetch(dataAccountAddress);
// assert on decoded accountUsing Default Programs
For testing that requires standard programs:
const mySigner = await generateKeyPairSigner();
const client = createClient().use(signer(mySigner)).use(litesvm());
// Add all default programs (System, BPF Loader, etc.)
client.svm.withDefaultPrograms();
// Or add specific programs you need
// The Token program, Associated Token program, etc. would need
// to be added manually via addProgramFromFile if neededBuild your Solana program with cargo build-sbf to generate the .so file.
The pattern is always the same:
- Program Loading: Use
addProgramFromFileto load compiled programs and import myProgramPlugin() from your client - Configuration: Enable sysvars, builtins, and precompiles as needed
- Account Setup: Pre-populate data accounts with
setAccount - Sending: Use
client.myProgram.testInstruction({..}).sendTransaction()— no manual transaction building - Verification: Check account state after execution (
client.myProgram.myAccount.fetch)
Once you have this skeleton working, you can build out a full test suite by adding more instructions and assertions.