Rust如何使用solana-program-test进行测试

我在学习Rust开发Solana程序时,遇到了单元测试的问题。想请教如何使用solana-program-test库来测试Solana程序?具体想了解:

  1. 如何搭建基本的测试环境?
  2. 如何模拟交易和账户状态?
  3. 有没有完整的测试示例可以参考?
  4. 测试过程中有哪些常见错误需要注意?

我的开发环境是Rust最新稳定版和Solana 1.9.x版本。希望能得到一些实际的代码示例和最佳实践建议。

2 回复

使用solana-program-test测试Rust智能合约:

  1. 添加依赖到Cargo.toml:
solana-program-test = "~1.16"
solana-sdk = "~1.16"
  1. 基本测试结构:
use solana_program_test::*;

#[tokio::test]
async fn test_my_program() {
    let program_id = Pubkey::new_unique();
    let mut program_test = ProgramTest::new("my_program", program_id, processor!(process_instruction));
    
    // 添加测试账户和交易
    // 执行测试断言
}
  1. 常用操作:
  • 模拟交易执行
  • 检查账户状态变化
  • 验证程序日志输出

简单实用,适合本地测试Solana程序。


在Rust中使用solana-program-test进行测试,可以模拟Solana链上环境,验证智能合约逻辑。以下是基本步骤和代码示例:

1. 添加依赖

Cargo.toml中添加:

[dependencies]
solana-program = "~1.16"
solana-program-test = "~1.16"
solana-sdk = "~1.16"
tokio = { version = "1", features = ["full"] }

2. 编写测试代码

use solana_program_test::*;
use solana_sdk::{
    account::Account,
    instruction::{AccountMeta, Instruction},
    pubkey::Pubkey,
    signature::Signer,
    transaction::Transaction,
};

// 定义程序ID
const PROGRAM_ID: Pubkey = Pubkey::new_from_array([...]); // 替换为实际程序ID

#[tokio::test]
async fn test_my_program() {
    // 初始化测试环境
    let program_id = PROGRAM_ID;
    let mut program_test = ProgramTest::new(
        "my_program",  // Cargo.toml中定义的程序名称
        program_id,
        processor!(my_program::process_instruction), // 入口函数
    );

    // 添加预置账户(可选)
    let user_pubkey = Pubkey::new_unique();
    let user_account = Account {
        lamports: 100_000_000, // 初始余额
        data: vec![],
        owner: program_id,
        executable: false,
        rent_epoch: 0,
    };
    program_test.add_account(user_pubkey, user_account);

    // 启动测试环境
    let (mut banks_client, payer, recent_blockhash) = program_test.start().await;

    // 构建指令
    let instruction = Instruction {
        program_id,
        accounts: vec![
            AccountMeta::new(user_pubkey, false),
            AccountMeta::new(payer.pubkey(), true),
        ],
        data: vec![], // 指令数据
    };

    // 创建并发送交易
    let mut transaction = Transaction::new_with_payer(
        &[instruction],
        Some(&payer.pubkey()),
    );
    transaction.sign(&[&payer], recent_blockhash);

    // 处理交易并验证结果
    banks_client.process_transaction(transaction).await.unwrap();

    // 可进一步查询账户状态验证逻辑
    let account = banks_client.get_account(user_pubkey).await.unwrap();
    assert!(account.is_some());
}

关键说明:

  • ProgramTest:模拟区块链环境,支持自定义账户和程序
  • BanksClient:提供与测试环境的交互接口
  • 指令构造:需正确设置账户元数据和指令数据
  • 交易处理:使用process_transaction执行并验证交易

常用验证方法:

  • 检查账户数据变化
  • 验证事件日志
  • 确认自定义错误类型

通过以上步骤,可在本地高效测试Solana程序逻辑,无需部署到开发网。

回到顶部