Blackbox calls
Overview
With the addition of unified syntax and new proxies, blackbox testing becomes the easiest and most accessible way to write integration tests for smart contracts. We can identify four types of transactions that can be ran in the testing environment:
- transaction - either a simple transfer or a contract call
- query - fetching values from the sc storage
- deploy - deploying a contract
- upgrade - upgrading a contract
As mentioned in TxEnv, in order to be able to create transactions in the testing environment, we need to create an instance of the ScenarioWorld
struct. In order to actually send the transaction, we need to finish it with .run()
.
Transaction
world // ScenarioWorld struct
.tx() // tx with testing environment
.from(OWNER_ADDRESS)
.to(ADDER_ADDRESS)
.typed(adder_proxy::AdderProxy) // typed call
.add(1u32)
.run(); // send transaction
In this example, we create a contract call to the adder
contract. We are using the proxy (AdderProxy
) to call the add
endpoint of the contract and we mark the end of the transaction and the start of the execution by using .run()
.
Query
world // ScenarioWorld struct
.query() // tx with testing query environment
.to(ADDER_ADDRESS)
.typed(adder_proxy::AdderProxy)
.sum()
.returns(ExpectValue(6u32)) // assert return value equals 6u32
.run(); // send transaction
In this example, we are querying the sum
view of the adder
contract through the proxy.
Deploy
let new_address = world // ScenarioWorld struct
.tx() // tx with testing environment
.from(OWNER_ADDRESS)
.typed(adder_proxy::AdderProxy)
.init(5u32) // deploy call
.code(CODE_PATH)
.new_address(ADDER_ADDRESS) // custom deploy address (only in tests)
.returns(ReturnsNewAddress)
.run(); // send transaction
In this example, we are deploying the adder
contract by calling it's init
endpoint through the proxy. The .new_address(ADDER_ADDRESS)
component is only present in tests for deploy transactions and signals that the contract should be deployed at a specific custom test address.
Upgrade
world // ScenarioWorld struct
.tx() // tx with testing environment
.from(OWNER_ADDRESS)
.to(ADDER_ADDRESS)
.typed(adder_proxy::AdderProxy)
.upgrade(100u64) // upgrade call
.code(CODE_PATH) // contract code
.run(); // send transaction
In order to upgrade the contract inside the testing environment, we need to call the upgrade
function through the proxy (as if it was an endpoint, similar to the deploy call). The upgrade call needs to know the contract code, so we always need to attach it to the transaction with .code(...)
.