Expand description
§Light Program Test
A fast local test environment for Solana programs using compressed accounts and tokens.
For Rust and Anchor program development, see light-sdk.
For Rust client, see light-client.
For full program examples, see the Program Examples.
For detailed documentation, visit zkcompression.com.
§Features
v2- Enables v2 batched Merkle trees.
§Testing Features
Use light-program-test when:
- You need fast test execution
- You write unit/integration tests for your program or client code
Use solana-test-validator when:
- You need RPC methods or external tools that are incompatible with LiteSVM
- Testing against real validator behavior
§Configuration Options
§with_prover: bool
true: Starts a prover server in the background for generating validity proofsfalse: Runs without prover (faster for tests that don’t need proofs, or repeated test runs to reduce startup time)
§additional_programs: Option<Vec<(&str, Pubkey)>>
- Specify custom programs to deploy alongside the default Light Protocol programs
- Format:
vec![("program_name", program_id)] - Programs are loaded from built artifacts
§Prerequisites
-
ZK Compression CLI: Required to start the prover server and download Light Protocol programs
npm i -g @lightprotocol/zk-compression-cli- If programs are missing after CLI installation, run
light test-validatoronce to download them
- If programs are missing after CLI installation, run
-
Build programs: Run
cargo test-sbfto build program binaries and set the required environment variables for locating program artifacts
§Prover Server
The prover server runs on port 3001 when enabled. To manually stop it:
# Find the process ID
lsof -i:3001
# Kill the process
kill <pid>§Debugging
Set RUST_BACKTRACE=1 to show detailed transaction information including accounts and parsed instructions:
RUST_BACKTRACE=1 cargo test-sbf -- --nocapture§Examples
§V1 Trees
use light_program_test::{LightProgramTest, ProgramTestConfig};
use solana_sdk::signer::Signer;
#[tokio::test]
async fn test_v1_compressed_account() {
// Initialize with v1 trees
let config = ProgramTestConfig::default();
let mut rpc = LightProgramTest::new(config).await.unwrap();
let payer = Keypair::new();
// Get v1 tree info
let address_tree_info = rpc.get_address_tree_v1();
let state_tree_info = rpc.get_random_state_tree_info();
// Airdrop for testing
rpc.airdrop_lamports(&payer.pubkey(), 1_000_000_000).await.unwrap();
// Query compressed accounts using Indexer trait
let accounts = rpc.indexer().unwrap()
.get_compressed_accounts_by_owner(&payer.pubkey())
.await
.unwrap();
println!("Found {} compressed accounts", accounts.len());
}§V2 Trees
use light_program_test::{LightProgramTest, ProgramTestConfig};
use solana_sdk::signer::Signer;
#[tokio::test]
async fn test_v2_compressed_account() {
// Initialize with v2 batched trees and custom program
let config = ProgramTestConfig::new_v2(
true, // with_prover
Some(vec![("my_program", my_program::ID)])
);
let mut rpc = LightProgramTest::new(config).await.unwrap();
let payer = Keypair::new();
// Get v2 tree pubkeys
let address_tree_info = rpc.get_address_tree_v2();
let state_tree_info = rpc.get_random_state_tree_info();
rpc.airdrop_lamports(&payer.pubkey(), 1_000_000_000).await.unwrap();
// Query using Indexer trait methods
let accounts = rpc.indexer().unwrap()
.get_compressed_accounts_by_owner(&payer.pubkey())
.await
.unwrap();
println!("Found {} compressed accounts with v2 trees", accounts.len());
}Re-exports§
pub use program_test::config::ProgramTestConfig;pub use program_test::LightProgramTest;
Modules§
- accounts
- compressible
- indexer
- logging
- Enhanced logging system for light-program-test
- program_
test - utils