> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# Bankrun

> Fast and lightweight testing for Solana programs using Bankrun.

## Overview

[Bankrun](https://kevinheavey.github.io/solders/tutorials/bankrun.html) is a fast, lightweight testing framework for Solana programs built on top of the Solana Banks client. It provides an ergonomic API for testing Solana programs without the overhead of running a full validator.

<Callout type="info">
  Bankrun is primarily used with Solders (Python) and provides similar functionality to LiteSVM, but with a different API design. For TypeScript and Rust testing, consider using \[LiteSVMtesting/litesvm) instead.
</Callout>

## Key Features

* **Fast Execution** - No validator startup time, tests run in-process
* **Lightweight** - Minimal resource usage compared to `solana-test-validator`
* **Direct SVM Access** - Tests programs directly against the Solana Virtual Machine
* **Python Support** - Part of the Solders Python library ecosystem
* **Time Control** - Manipulate clock and slot for testing time-dependent logic

## When to Use Bankrun

Bankrun is ideal for:

* **Python-based testing** - If your testing workflow uses Python
* **Fast iteration** - When you need quick test feedback loops
* **Unit testing** - Testing individual program instructions in isolation
* **CI/CD pipelines** - Faster test execution in automated environments

## Installation

Bankrun is included as part of the Solders library:

```bash theme={null}
# Using pip
pip install solders

# Using uv (recommended)
uv add solders
```

## Basic Usage

Here's a simple example of testing a Solana program transfer:

```python theme={null}
from solders.bankrun import start
from solders.keypair import Keypair
from solders.system_program import transfer, TransferParams
from solders.transaction import Transaction

# Start the test environment
context = await start([], [])

# Create test keypairs
payer = Keypair()
recipient = Keypair()

# Airdrop SOL to payer
await context.set_account(
    payer.pubkey(),
    Account(lamports=1_000_000_000, owner=SYSTEM_PROGRAM_ID)
)

# Create transfer instruction
instruction = transfer(
    TransferParams(
        from_pubkey=payer.pubkey(),
        to_pubkey=recipient.pubkey(),
        lamports=100_000,
    )
)

# Build and process transaction
tx = Transaction.new_with_payer([instruction], payer.pubkey())
await context.process_transaction(tx, [payer])

# Verify results
recipient_account = await context.get_account(recipient.pubkey())
assert recipient_account.lamports == 100_000
```

## Testing Anchor Programs

To test an Anchor program with Bankrun, you'll need to:

1. Build your program with `anchor build`
2. Load the program binary in your test
3. Create and process instructions

```python theme={null}
import asyncio
from pathlib import Path
from solders.bankrun import start
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solders.instruction import Instruction, AccountMeta
from solders.transaction import Transaction

async def test_anchor_program():
    # Load program binary
    program_id = Pubkey.from_string("YourProgramID111111111111111111111111111")
    program_path = Path("target/deploy/my_program.so")
    
    with open(program_path, "rb") as f:
        program_data = f.read()
    
    # Start test environment with program
    context = await start(
        [(program_id, Account(data=program_data, executable=True, owner=BPF_LOADER_UPGRADEABLE_ID))],
        []
    )
    
    # Create test accounts
    user = Keypair()
    my_account = Keypair()
    
    # Airdrop SOL to user
    await context.set_account(
        user.pubkey(),
        Account(lamports=1_000_000_000, owner=SYSTEM_PROGRAM_ID)
    )
    
    # Create initialize instruction
    instruction = Instruction(
        program_id=program_id,
        accounts=[
            AccountMeta(my_account.pubkey(), is_signer=True, is_writable=True),
            AccountMeta(user.pubkey(), is_signer=True, is_writable=False),
            AccountMeta(SYSTEM_PROGRAM_ID, is_signer=False, is_writable=False),
        ],
        data=bytes([0]),  # Instruction discriminator
    )
    
    # Process transaction
    tx = Transaction.new_with_payer([instruction], user.pubkey())
    await context.process_transaction(tx, [user, my_account])
    
    # Verify account was created
    account = await context.get_account(my_account.pubkey())
    assert account is not None
    assert account.owner == program_id

# Run the test
asyncio.run(test_anchor_program())
```

## Time Manipulation

Bankrun allows you to manipulate the clock for testing time-dependent programs:

```python theme={null}
from solders.bankrun import start
from solders.clock import Clock

# Start test environment
context = await start([], [])

# Get current clock
clock = await context.get_sysvar(Clock)
print(f"Current timestamp: {clock.unix_timestamp}")

# Advance time by 1 hour (3600 seconds)
new_clock = Clock(
    slot=clock.slot + 7200,  # ~1 hour at 400ms per slot
    epoch_start_timestamp=clock.epoch_start_timestamp,
    epoch=clock.epoch,
    leader_schedule_epoch=clock.leader_schedule_epoch,
    unix_timestamp=clock.unix_timestamp + 3600,
)

await context.set_sysvar(new_clock)

# Now test time-dependent logic
# ...
```

## Comparison with Other Testing Frameworks

| Feature                | Bankrun      | LiteSVM          | solana-test-validator |
| ---------------------- | ------------ | ---------------- | --------------------- |
| **Language**           | Python       | Rust, TS, Python | All                   |
| **Speed**              | Fast         | Fastest          | Slow                  |
| **Setup**              | Minimal      | Minimal          | Complex               |
| **RPC Support**        | No           | No               | Yes                   |
| **Validator Behavior** | Minimal      | Minimal          | Full                  |
| **Best For**           | Python tests | Unit tests       | Integration tests     |

## Testing Best Practices

1. **Use fixtures** - Create reusable test fixtures for common setups
2. **Test isolation** - Each test should start with a fresh context
3. **Async patterns** - Leverage Python's async/await for better test structure
4. **Error cases** - Test both success and failure scenarios
5. **State verification** - Always verify account states after operations

## Example: Full Test Suite

```python theme={null}
import pytest
import asyncio
from pathlib import Path
from solders.bankrun import start
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solders.system_program import ID as SYSTEM_PROGRAM_ID
from solders.instruction import Instruction, AccountMeta
from solders.transaction import Transaction

class TestMyProgram:
    @pytest.fixture
    async def context(self):
        """Set up test context with program loaded"""
        program_id = Pubkey.from_string("YourProgramID111111111111111111111111111")
        program_path = Path("target/deploy/my_program.so")
        
        with open(program_path, "rb") as f:
            program_data = f.read()
        
        ctx = await start(
            [(program_id, Account(data=program_data, executable=True))],
            []
        )
        return ctx, program_id
    
    @pytest.mark.asyncio
    async def test_initialize(self, context):
        """Test account initialization"""
        ctx, program_id = context
        user = Keypair()
        
        # Airdrop SOL
        await ctx.set_account(
            user.pubkey(),
            Account(lamports=1_000_000_000, owner=SYSTEM_PROGRAM_ID)
        )
        
        # Test initialization
        # ...
        assert True  # Replace with actual assertions
    
    @pytest.mark.asyncio
    async def test_invalid_input(self, context):
        """Test error handling"""
        ctx, program_id = context
        
        # Test should fail with invalid data
        with pytest.raises(Exception):
            # Attempt invalid operation
            pass
```

## Limitations

* **No RPC methods** - Direct account access only, no RPC API
* **Python only** - Not available for TypeScript or Rust tests
* **Minimal validator behavior** - Doesn't simulate all validator features
* **Limited ecosystem** - Fewer examples and community resources compared to LiteSVM

## When to Use solana-test-validator Instead

Consider using `solana-test-validator` when you need:

* Full RPC method support
* Testing validator-specific behavior
* Integration with external tools and services
* Testing complex multi-program interactions
* Realistic production-like testing environment

## Additional Resources

* [Solders Documentation](https://kevinheavey.github.io/solders/)
* [Bankrun Tutorial](https://kevinheavey.github.io/solders/tutorials/bankrun.html)
* [Solana Banks Client](https://docs.rs/solana-banks-client/)
* \[LiteSVM Alternativetesting/litesvm)

## Next Steps

* Explore \[LiteSVMtesting/litesvm) for multi-language testing
* Learn about \[Mollusktesting/mollusk) for Rust unit testing
* Read the \[Testing Overviewtesting/overview) for testing strategies
