Skip to main content

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(...).