Conceptos básicos de pruebas
8 ejemplos para empezar con las pruebas de programas de Solana: 5 básicos y 3 intermedios. Cubre la pirámide de pruebas: pruebas unitarias LiteSVM 0.6.x, pruebas de instrucciones Mollusk, integración Anchor TS y E2E del validador.
Prerrequisitos
- Espacio de trabajo de Anchor 0.32.1 con
anchor testconfigurado. - Toolchain de Rust 1.91.1.
- Opcional:
@solana/kit7.0.0 para pruebas del lado del cliente.
anchor --version # 0.32.1
cargo test --versionEjemplos básicos
1. Ejecutar pruebas de Anchor
La prueba de integración predeterminada inicia un validador local.
anchor test- Compila el programa, lo implementa en un validador local y ejecuta
tests/*.ts. - Utiliza el clúster del proveedor de
Anchor.toml. - Más lento que LiteSVM, pero ejercita la ruta RPC completa.
Relacionado: Pruebas Anchor TS
2. Prueba de humo LiteSVM
SVM en proceso sin proceso 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();- Iteración sub-milisegundo para la lógica de instrucciones.
- Carga
.soconsvm.add_program. - Ideal para pruebas de seguridad negativas.
Relacionado: LiteSVM
3. Arnés de instrucciones Mollusk
Ejecutor ligero a nivel de instrucción en pruebas de 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);- Configuración más rápida que el conjunto completo de Anchor para desarrolladores de Rust puros.
- Buena capa intermedia entre LiteSVM y el validador.
Relacionado: Mollusk
4. Error del programa de aserción
Las pruebas negativas son obligatorias para la seguridad.
try {
await program.methods.badWithdraw().rpc();
throw new Error("expected fail");
} catch (e) {
// expect anchor error code
}- Coincide con los códigos de error del enum
#[error_code]. - Prueba firmante ausente, mint incorrecto, rutas de oráculo obsoletas.
- Una prueba por clase de ataque del catálogo.
Relacionado: Catálogo de ataques de Sealevel
5. Restablecer el validador local en CI
La CI determinista requiere un ledger limpio.
solana-test-validator --reset --quiet &
anchor test --skip-local-validator--resetborra el estado entre ejecuciones.- Fija el binario del validador Agave 4.1.1 en la imagen de CI.
- Mata validadores huérfanos en el puerto 8899.
Relacionado: Pruebas contra un validador
Ejemplos intermedios
6. Derivación de PDA de prueba
El cliente y el programa deben acordar las semillas.
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), user.toBuffer()],
program.programId
);
const account = await program.account.vault.fetch(pda);- Compara el bump almacenado en la cadena con la derivación del cliente.
- Falla las pruebas si las cadenas de semillas no coinciden (
b"vault"vs"vault").
Relacionado: Pruebas de CPI y PDA
7. Integración de bifurcación de Surfpool
Las pruebas de DeFi necesitan el estado del pool de 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 superpone el estado de bifurcación para cadenas CPI realistas.
- Úsalo para pruebas de integración de Jupiter/AMM solo cuando sea necesario.
8. Límites de depósito de fuzzing
Las pruebas de propiedades encuentran los bordes de desbordamiento.
cargo fuzz run deposit_fuzz -- -max_total_time=300- Trident/fuzz apunta a cantidades aleatorias y banderas de cuenta.
- Ejecuta fuzz extendido antes de la auditoría (Fuzzing de programas).
Versiones de la pila: Esta página se escribió 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 y LiteSVM 0.6.x.