Bắt Đầu
let mut svm = LiteSVM::new();
Lệnh này tạo ra phiên bản kiểm thử litesvm cơ bản, bao gồm tất cả các tính năng runtime được kích hoạt, sysvars mặc định, precompiles, các chương trình spl, sigverify, và tất cả các chương trình tích hợp sẵn như System Program.
Để tương tác với bất kỳ chương trình nào khác trong các bài kiểm thử của bạn, bạn phải triển khai chương trình đó vào môi trường kiểm thử của mình.
-
Build và triển khai chương trình bạn muốn kiểm thử
-
Tìm tất cả các chương trình mà chương trình trên thực hiện lời gọi CPI và triển khai các chương trình đó
Ví dụ: Nếu chương trình của bạn đang sử dụng nguồn dữ liệu từ Pyth, bạn sẽ cần triển khai chương trình Pyth vào phiên bản kiểm thử của mình.
Triển Khai Chương Trình Cơ Bản
Phương Pháp 1: Triển Khai Từ Bytes
Triển khai chương trình trực tiếp từ mảng byte để đạt tốc độ thực thi kiểm thử nhanh nhất:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read the program's keypair to get correct IDlet program_keypair = read_keypair_file("target/deploy/my_program-keypair.json").expect("Program keypair file not found");let program_id = program_keypair.pubkey();// Include bytes at compile timelet program_bytes = include_bytes!("../target/deploy/my_program.so");// Deploy from bytessvm.add_program(program_id, program_bytes).expect("Failed to deploy program");// Verify deploymentassert!(svm.get_account(&program_id).is_some(), "Program account not created");assert!(svm.get_account(&program_id).unwrap().executable, "Program not executable");
include_bytes! nhúng binary trực tiếp vào tệp thực thi kiểm thử tại thời điểm
biên dịch, loại bỏ I/O trong quá trình thực thi kiểm thử.
✓ Ưu điểm
- •Nhanh hơn khi chạy (không đọc đĩa)
- •Tệp binary kiểm thử độc lập
- •Hoạt động ngay cả khi tệp .so bị xóa sau khi biên dịch
✗ Nhược điểm
- •Kích thước tệp binary kiểm thử lớn hơn
- •Phải biên dịch lại các bài kiểm thử khi tệp .so thay đổi
Phương pháp 2: Triển khai từ tệp (.so)
Tải chương trình từ hệ thống tệp khi chúng thay đổi thường xuyên:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read keypair for correct program IDlet program_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = program_keypair.pubkey();// Deploy from filesvm.add_program_from_file(program_id, "target/deploy/program.so").expect("Failed to deploy program from file");// Always verifyassert!(svm.get_account(&program_id).unwrap().executable);
✓ Ưu điểm
- •Tệp nhị phân kiểm thử nhỏ hơn
- •Có thể nhận thay đổi .so mà không cần biên dịch lại các bài kiểm thử
- •Linh hoạt hơn cho các pipeline CI/CD
✗ Nhược điểm
- •Chậm hơn (I/O đĩa khi chạy)
- •Yêu cầu tệp .so phải tồn tại tại thời điểm thực thi kiểm thử
- •Đường dẫn tệp phải chính xác so với thư mục thực thi kiểm thử
Lấy chương trình từ Mainnet/Devnet
Khi bạn cần một chương trình mà bạn không có mã nguồn, hãy sử dụng Solana CLI để kết xuất các chương trình từ các cluster đang hoạt động và sử dụng chúng trong các bài kiểm thử:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Sau đó tải nó trong các bài kiểm thử của bạn:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Các phương pháp hay nhất
1. Chọn phương pháp triển khai phù hợp
-
Sử dụng
add_program()khi:- Các chương trình được nhúng vào tệp nhị phân kiểm thử của bạn tại thời điểm biên dịch
- Bạn muốn thực thi kiểm thử nhanh hơn (không có I/O khi chạy)
- Các bài kiểm thử khép kín
-
Sử dụng
add_program_from_file()khi:- Các chương trình được build riêng biệt (tức là lấy từ devnet)
- Chương trình thay đổi thường xuyên trong quá trình phát triển (có thể chạy lại các bài kiểm tra mà không cần biên dịch lại)
- Bạn có môi trường CI/CD nơi các file .so là các artifact
Hiểu về Program keypair
Khi bạn build một chương trình Solana:
- Anchor tạo
target/deploy/program-keypair.json - Native build tạo một file keypair cùng với file
.so - Địa chỉ on-chain của chương trình là khóa công khai của keypair này, còn được gọi là program ID.
- Đối với PDAs,
find_program_address()yêu cầu program ID là một seed - Đối với CPIs, program ID được dùng để gọi các chương trình khác
Các Vấn Đề Thường Gặp và Giải Pháp
Lỗi Triển Khai Âm Thầm
Vấn đề: Chương trình có vẻ được triển khai nhưng các giao dịch thất bại với lỗi "InvalidProgramForExecution".
Nguyên nhân: Program ID không khớp với keypair.
Giải pháp:
// Always use the keypair-derived IDlet keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();svm.add_program(program_id, &program_bytes).unwrap();// Verify with detailed checkslet account = svm.get_account(&program_id).expect("Program account doesn't exist");assert!(account.executable, "Program not executable");assert_eq!(account.owner, solana_sdk::bpf_loader::id(), "Wrong owner");assert!(!account.data.is_empty(), "Program data is empty");println!("✅ Program verified at {}", program_id);
Lỗi Không Tìm Thấy Chương Trình
Lỗi: TransactionError::InvalidProgramForExecution
Nguyên nhân Thường Gặp:
- Chương trình chưa được triển khai
- Sử dụng sai program ID trong lệnh
- Program ID không khớp với keypair
Các Bước Gỡ Lỗi:
// Step 1: Check if program existsif let Some(account) = svm.get_account(&program_id) {println!("Program exists");println!(" Executable: {}", account.executable);println!(" Owner: {}", account.owner);println!(" Data length: {}", account.data.len());} else {println!("Program does not exist at {}", program_id);}// Step 2: Verify the ID matches keypairlet expected_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let expected_id = expected_keypair.pubkey();if program_id != expected_id {println!(" ID mismatch!");println!(" Used: {}", program_id);println!(" Expected: {}", expected_id);}// Step 3: Check instruction program IDprintln!("Instruction program_id: {}", instruction.program_id);assert_eq!(instruction.program_id, program_id, "Instruction uses wrong program ID");
CPI Đến Các Chương Trình Chưa Triển Khai
Vấn đề: Chương trình của bạn thực hiện lời gọi CPI đến một chương trình chưa được triển khai.
Giải pháp: Triển khai tất cả các chương trình phụ thuộc:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Nếu bạn cần lấy chương trình từ một cluster, hãy xem lại phần này.
Không Đủ lamport để Triển Khai
Lưu ý: LiteSVM tự động xử lý số dư miễn phí tiền thuê cho các chương trình.
// No need to manually fund - LiteSVM handles thissvm.add_program(program_id, &program_bytes).unwrap();// But you can check the rent if neededlet program_len = program_bytes.len();let required_lamports = svm.minimum_balance_for_rent_exemption(program_len);println!("Program requires {} lamports for rent exemption", required_lamports);
Danh Sách Kiểm Tra Xác Minh Triển Khai
Đọc keypair của chương trình
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Triển khai với ID khớp
svm.add_program(program_id, &program_bytes).unwrap();
Xác minh việc triển khai
assert!(svm.get_account(&program_id).unwrap().executable);
Triển khai bất kỳ chương trình nào mà chương trình của bạn gọi qua CPI vào instance kiểm thử litesvm
Các Bước Tiếp Theo
Trong phần tiếp theo, chúng ta sẽ tìm hiểu cách thực thi các lệnh của chương trình và xử lý các mẫu giao dịch phức tạp.
Is this page helpful?