Writing Tests with Blueprint
Overview
Test toolkit (usually sandbox) is already included in the TypeScript SDK named Blueprint. You can create a demo project and launch the default test with 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 of smart contracts allows for the coverage of security, optimization of gas spending, and examination of edge cases. Writing tests in Blueprint (based on Sandbox) works through defining arbitrary actions with the contract and comparing test results with the expected result, for example:
it('should execute with success', async () => { // description of the test case
const res = await main.sendMessage(sender.getSender(), toNano('0.05')); // performing an action with contract main and saving result in res
expect(res.transactions).toHaveTransaction({ // configure the expected result with expect() function
from: main.address, // set expected sender for transaction we want to test matcher properties from
success: true // set the desirable result using matcher property success
});
printTransactionFees(res.transactions); // print table with details on spent fees
});
Writing Tests for Complex Assertion
The basic workflow of creating a test is:
- Create a specific wrapped
Contract
entity usingblockchain.openContract()
. - Describe the actions your
Contract
should perform and save the execution result inres
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 of the property to ). |
value | bigint? | Amount of Toncoins in the message in nanotons |
body | Cell | Message body defined as a Cell |
op | number? | Op code is the operation identifier number (crc32 from TL-B usually). 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 phase succeeded. Otherwise - False. |
You can omit the fields that you're not interested in and pass functions accepting the types returning booleans (true
meaning good) to check for example number ranges, message opcodes, etc. Please note that if a field is optional (like from?: Address
), then the function needs to accept the optional type, too.
You can learn the whole list of matcher fields from the Sandbox documentation.
Specific Test Suite
Extract SendMode
To extract the send mode of a sent message you can 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