# Testing smart contracts with Blueprint (https://docs-kyrm16yq7-ton-core-docs.vercel.app/llms/contract-dev/blueprint/testing/overview/content.md)



<Callout type="note">
  [Acton](/llms/contract-dev/acton/content.md) is the recommended tool for new smart contract projects. Blueprint remains supported for existing projects.
</Callout>

TON Sandbox ([`@ton/sandbox`](https://github.com/ton-org/sandbox)) is a local blockchain emulator that allows you to test smart contracts from TypeScript, without deploying them to a real network, and without running a blockchain node. It provides a complete testing environment that closely mimics the behavior of the actual TON blockchain. [Blueprint](/llms/contract-dev/blueprint/overview/content.md) project template already includes the `@ton/sandbox` dependency.

The companion `@ton/test-utils` helper library provides [matchers](https://jestjs.io/docs/using-matchers) for writing tests with Jest.

This guide covers everything you need to know about writing, running, and debugging tests for your smart contracts. For other programming languages consult documentation of corresponding [SDKs](/llms/ecosystem/sdks/content.md).

### Sandbox vs real network [#sandbox-vs-real-network]

| Feature       | Sandbox            | Real Network                       |
| ------------- | ------------------ | ---------------------------------- |
| Speed         | Instant execution  | \~5-15 second finality             |
| Cost          | Free               | Requires real TON                  |
| Deterministic | Yes                | No (depends on network conditions) |
| Debugging     | Full introspection | Limited visibility                 |
| State Control | Complete control   | Immutable history                  |

### Sandbox limitations [#sandbox-limitations]

While Sandbox closely emulates the real network, there are some differences to be aware of:

* **Time-dependent contracts**: Sandbox time is controlled, not real-time
* **External dependencies**: Cannot interact with real external contracts, but can get their state and emulate them
* **Blockchain imitation**: Because there is no concept of blocks in Sandbox, things like sharding do not work.

## Writing tests [#writing-tests]

Blueprint uses Jest as the default testing framework, providing powerful assertion capabilities and excellent TypeScript support.

### Basic test setup [#basic-test-setup]

Every Blueprint project includes a test template. Here's the standard structure:

```typescript title="tests/MyContract.spec.ts" expandable
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { Cell, toNano } from '@ton/core';
import { MyContract } from '../wrappers/MyContract';
import '@ton/test-utils';
import { compile } from '@ton/blueprint';

describe('MyContract', () => {
    let code: Cell;

    beforeAll(async () => {
        code = await compile('MyContract');
    });

    let blockchain: Blockchain;
    let deployer: SandboxContract<TreasuryContract>;
    let myContract: SandboxContract<MyContract>;

    beforeEach(async () => {
        blockchain = await Blockchain.create();

        myContract = blockchain.openContract(
            MyContract.createFromConfig({}, code)
        );

        deployer = await blockchain.treasury('deployer');

        const deployResult = await myContract.sendDeploy(
            deployer.getSender(),
            toNano('0.05')
        );

        expect(deployResult.transactions).toHaveTransaction({
            from: deployer.address,
            to: myContract.address,
            deploy: true,
            success: true,
        });
    });

    it('should deploy', async () => {
        // Contract is already deployed in beforeEach
        // Add additional deployment checks here
    });
});
```

### Test isolation [#test-isolation]

Each test should include a fresh `Blockchain` instance to ensure:

**Test isolation**

* No state leakage between tests
* Predictable initial conditions
* Independent contract deployments

**Clean environment**

* Fresh treasury wallets
* Reset logical time and configuration
* Clear transaction history

```typescript
beforeEach(async () => {
    // Fresh blockchain for each test
    blockchain = await Blockchain.create();

    // Each test gets clean treasuries
    deployer = await blockchain.treasury('deployer');
    user = await blockchain.treasury('user');
});
```

### Understanding transaction results [#understanding-transaction-results]

When you send a message to a contract, you receive a `SendMessageResult` containing:

```typescript
const result = await contract.sendIncrement(user.getSender(), toNano('0.1'));

// result.transactions - Array of all transactions in the chain
// result.events - Blockchain events emitted
// result.externals - External messages generated
```

### Transaction matchers [#transaction-matchers]

Blueprint provides powerful matchers for validating transactions:

```typescript
expect(result.transactions).toHaveTransaction({
    from: user.address,
    to: contract.address,
    value: toNano('1'),
    op: 0x12345678, // Operation code
    success: true,
    outMessagesCount: 2, // Number of outbound messages
    deploy: false,
    body: beginCell()
        .storeUint(0, 32) // Comment op
        .storeStringTail("Hello, user!")
        .endCell()
});
```

## Running tests [#running-tests]

```bash
# Run all tests
npx blueprint test

# Run specific test file
npx blueprint test MyContract

# Run with coverage
npx blueprint test --coverage

# Run with gas reporting
npx blueprint test --gas-report
```

## Common pitfalls [#common-pitfalls]

<Callout type="caution">
  **Avoid These Common Mistakes**

  1. **Shared State**: Don't reuse blockchain instances between tests
  2. **Async Issues**: Always await blockchain operations
  3. **Time Dependencies**: Use `blockchain.now` for time-sensitive tests
  4. **Gas Limits**: Be aware of the computation and action phase limits
  5. **Message Ordering**: Remember that message processing is sequential
  6. **Treasury Reuse**: Use unique seeds for different test scenarios
</Callout>

### Debugging checklist [#debugging-checklist]

When tests fail, check these common issues:

* ✅ Contract is properly deployed before testing
* ✅ Treasury has sufficient balance for operations
* ✅ Transaction matchers use correct field names
* ✅ Exit codes match expected error conditions
* ✅ Message bodies are correctly formatted
* ✅ Time-sensitive operations account for blockchain time

## Other resources [#other-resources]

* [Debug Guide](/llms/contract-dev/debug/content.md) — Advanced debugging techniques
* [TON Dev Wallet](https://github.com/TonDevWallet/TonDevWallet) — Visual debugging tool
