Testing with NodeJS
When developing programs on Solana, ensuring their correctness and reliability
is crucial. Until now devs have been using solana-test-validator
for testing.
This document covers testing your Solana program with Node.js
using solana-bankrun
.
Overview
There are two ways to test programs on Solana:
- solana-test-validator: That spins up a local emulator of the Solana Blockchain on your local machine which receives the transactions to be processed by the validator.
- The various BanksClient-based test frameworks for SBF (Solana Bytecode Format) programs: Bankrun is a framework that simulates a Solana bank's operations, enabling developers to deploy, interact with, and assess the behavior of programs under test conditions that mimic the mainnet. It helps set up the test environment and offers tools for detailed transaction insights, enhancing debugging and verification. With the client, we can load programs, and simulate and process transactions seamlessly. solana-program-test (Rust), solana-bankrun (Rust, JavaScript), anchor-bankrun (Anchor, JavaScript), solders.bankrun (Python) are examples of the BanksClient-based testing framework.
pnpm create solana-program
can help you generate JS and Rust clients including tests. Anchor is not yet supported.
In this guide, we are using Solana Bankrun. Bankrun
is a superfast, powerful,
and lightweight framework for testing Solana programs in Node.js.
- The biggest advantage of using Solana Bankrun is that you don't have to set
up
an environment to test programs like you'd have to do while using the
solana-test-validator
. Instead, you can do that with a piece of code, inside
the tests. - It also dynamically sets time and account data, which isn't possible with
solana-test-validator
Installation
Add solana-bankrun
as a dev dependency to your node project. If your Solana
program is not a node project yet, you can initialize it using npm init
.
Usage
Program Directory
Firstly, the program's .so
file must be present in one of the following
directories:
./tests/fixtures
(just create this directory if it doesn't exist already).- Your current working directory.
- A directory you define in the
BPF_OUT_DIR
orSBF_OUT_DIR
environment variables.export BPF_OUT_DIR='/path/to/binary'
- Build your program specifying the correct directory so that library can pick
the file up from directory just from the name.
cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures
Testing Framework
solana-bankrun is used in JavaScript or TypeScript with testing frameworks like
ts-mocha,
ava, Jest,
etc. Make sure to get started with any of the above.
Add an npm script to test
your program and create your test.ts
file inside tests
folder.
Start
start
function from solana-bankrun
spins up a BanksServer and a BanksClient,
deploy programs and add accounts as instructed.
Bankrun context
-
We get access to the Bankrun
context
from thestart
function. Context contains a BanksClient, a recent blockhash and a funded payer keypair. -
context
has apayer
, which is a funded keypair that can be used to sign transactions. -
context
also hascontext.lastBlockhash
orcontext.getLatestBlockhash
to make fetching Blockhash convenient during tests. -
context.banksClient
is used to send transactions and query account data from the ledger state. For example, sometimes Rent (in lamports) is
required to build a transaction to be submitted, for example, when using the SystemProgram's
createAccount() instruction. You can do that using BanksClient: -
You can read account data from BanksClient using
getAccount
function
Process Transaction
The processTransaction()
function executes the transaction with the loaded
programs
and accounts from the start function and will return a transaction.
Example
Here's an example to write test for a hello world program :
This is how the output looks like after running the tests for hello world program.