Noções básicas de testes
8 exemplos para começar com testes de programas Solana - 5 básicos e 3 intermediários. Cobre a pirâmide de testes: testes unitários LiteSVM 0.6.x, testes de instrução Mollusk, integração Anchor TS e E2E com validador.
Pré-requisitos
- Workspace Anchor 0.32.1 com
anchor testconfigurado. - Toolchain Rust 1.91.1.
- Opcional:
@solana/kit7.0.0 para testes client-side.
anchor --version # 0.32.1
cargo test --versionExemplos básicos
1. Executar testes Anchor
Teste de integração padrão sobe validador local.
anchor test- Compila programa, faz deploy no validador local, executa
tests/*.ts. - Usa cluster do provider de
Anchor.toml. - Mais lento que LiteSVM mas exercita caminho RPC completo.
Relacionado: Testes Anchor TS
2. Smoke test LiteSVM
SVM in-process sem processo de validador.
use litesvm::LiteSVM;
use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction};
let mut svm = LiteSVM::new();
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();- Iteração sub-milissegundo para lógica de instrução.
- Carregue
.socomsvm.add_program. - Ideal para testes negativos de segurança.
Relacionado: LiteSVM
3. Harness de instrução Mollusk
Runner leve em nível de instrução em testes Rust.
use mollusk_svm::Mollusk;
use solana_sdk::instruction::{AccountMeta, Instruction};
let mollusk = Mollusk::new(&program_id, "target/deploy/my_program");
let ix = Instruction { program_id, accounts: vec![], data: vec![] };
mollusk.process_instruction(&ix, &accounts);- Setup mais rápido que suite Anchor completa para devs Rust puros.
- Boa camada intermediária entre LiteSVM e validador.
Relacionado: Mollusk
4. Assertar erro de programa
Testes negativos são obrigatórios para segurança.
try {
await program.methods.badWithdraw().rpc();
throw new Error("expected fail");
} catch (e) {
// expect anchor error code
}- Combine códigos de erro do enum
#[error_code]. - Teste signer ausente, mint errado, caminhos de oracle obsoleto.
- Um teste por classe de ataque do catálogo.
Relacionado: Catálogo Sealevel Attacks
5. Resetar validador local no CI
CI determinístico exige ledger limpo.
solana-test-validator --reset --quiet &
anchor test --skip-local-validator--resetlimpa estado entre execuções.- Fixe binário validador Agave 4.1.1 na imagem CI.
- Mate validadores órfãos na porta 8899.
Relacionado: Testando contra validador
Exemplos intermediários
6. Testar derivação de PDA
Cliente e programa devem concordar nas seeds.
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), user.toBuffer()],
program.programId
);
const account = await program.account.vault.fetch(pda);- Compare bump armazenado on-chain com derivação do cliente.
- Falhe testes se strings de seed não coincidirem (
b"vault"vs"vault").
Relacionado: Testando CPIs e PDAs
7. Integração Surfpool fork
Testes DeFi precisam de estado de pool mainnet.
surfpool start --rpc-url https://api.mainnet-beta.solana.com
export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
anchor test --skip-local-validator- Surfpool 0.12.0 sobrepõe estado fork para cadeias CPI realistas.
- Use para testes de integração Jupiter/AMM apenas quando necessário.
8. Fuzz de limites de depósito
Testes de propriedade encontram bordas de overflow.
cargo fuzz run deposit_fuzz -- -max_total_time=300- Alvos Trident/fuzz com valores e flags de conta aleatórios.
- Execute fuzz estendido antes da auditoria (Fuzzing de programas).
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.