Writing tests with Blueprint
Overview
The TypeScript SDK, named Blueprint, already includes the test toolkit (usually Sandbox). You can create a demo project and run the default test in two steps:
- Create a new Blueprint project:
npm create ton@latest MyProject
- Run a test:
cd MyProject
npx blueprint test
As a result, you’ll see the corresponding output in the terminal window:
% npx blueprint test
> [email protected] test
> jest
PASS tests/Main.spec.ts
Main
✓ should deploy (127 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.224 s, estimated 2 s
Ran all test suites.
Basic usage
Testing smart contracts allows you to cover security, optimize gas spending, and examine edge cases.
Writing tests in Blueprint (based on Sandbox) involves defining arbitrary actions with the contract and comparing the test results with the expected outcome. For example:
it("should execute with success", async () => {
// Description of the test case
const res = await main.sendMessage(sender.getSender(), toNano("0.05")); // Perform an action with the contract and save the result in res
expect(res.transactions).toHaveTransaction({
// Configure the expected result with the expect() function
from: main.address, // Set the expected sender for the transaction
success: true, // Set the desirable result using the matcher property success
});
printTransactionFees(res.transactions); // Print a table with details on spent fees
});
Writing tests for complex assertions
The basic workflow for creating a test is as follows:
- Create a specific wrapped
Contract
entity usingblockchain.openContract()
. - Describe the actions your
Contract
should perform and save the execution result in theres
variable. - Verify the properties using the
expect()
function and the matchertoHaveTransaction()
.
The toHaveTransaction
matcher expects an object with any combination of fields from the FlatTransaction
type, defined with the following properties:
Name | Type | Description |
---|---|---|
from | Address? | Contract address of the message sender |
on | Address | Contract address of the message destination (alternative name for the property to ). |
value | bigint? | Amount of TON coins in the message, in nanotons |
body | Cell | Message body defined as a Cell |
op | number? | Op code is usually the operation identifier number (crc32 from TL-B). Expected in the first 32 bits of a message body. |
success | boolean? | Custom Sandbox flag that defines the resulting status of a certain transaction. True if both the compute and the action phases succeeded. Otherwise, False. |
You can omit fields you’re not interested in and pass functions that accept the types and return booleans (true
meaning good) to check, for example, number ranges, message opcodes, etc. Note that if a field is optional (like from?: Address
), the function must also accept the optional type.
The complete list of matcher fields is in the Sandbox documentation.
Specific test suite
Extract send mode
To extract the send mode of a sent message, use the following code:
const re = await blockchain.executor.runTransaction({
message: beginCell().endCell(),
config: blockchain.configBase64,
libs: null,
verbosity: "short",
shardAccount: beginCell()
.storeAddress(address)
.endCell()
.toBoc()
.toString("base64"),
now: Math.floor(Date.now()) / 1000,
lt: BigInt(Date.now()),
randomSeed: null,
ignoreChksig: false,
debugEnabled: true,
});
if (!re.result.success || !re.result.actions) {
throw new Error("fail");
}
const actions = loadOutList(Cell.fromBase64(re.result.actions).beginParse());
for (const act of actions) {
if (act.type === "sendMsg") {
// process action
console.log(act.mode);
}
}
Tutorials
Learn more about testing from the most valuable community tutorials on TON:
- Lesson 2: Testing FunC for a Smart Contract
- TON Hello World part 4: Step-by-step guide for testing your first smart contract
- TON Smart Contract Pipeline
- [YouTube] Sixth lesson FunC & Blueprint: Gas, fees, tests
Examples
Check test suites used for TON Ecosystem contracts and learn by examples:
- Liquid-staking-contract sandbox tests
- Governance_tests
- JettonWallet.spec.ts
- Governance_tests
- MassSender.spec.ts
- Assurer.spec.ts