Custom Tests
In this section, I will give you a test for the cw-ica-controller
contract. This test demonstrates how to create a new interchain account, fund it, and then stake some tokens with it. And then we will go over this test file line by line to understand the logic behind it.
Replace the contents of e2e/interchaintestv8/contract_test.go
with the following code:
loading...
You need to run go mod tidy
to update the indirect dependencies.
go mod tidy
Organization
The tests are organized into subtests using the s.Run
method. This method takes a test name and a test function as arguments. The test function is executed when the test is run.
loading...
Best Practice: Using `s.Run`
Using the s.Run
method to organize your tests into subtests makes it easier to understand the purpose of each test and helps you to identify the failing test quickly.
Notice that each s.Run
call is also wrapped by a s.Require().True
call. This is because without this, sequential subtests will be executed even if the previous subtest fails. You may abstain from doing this if you want to run the subtests even if one of them fails.
Test Logic
We will do a line-by-line analysis of the test logic.
We first call the underlying test suite's setup method. This is where the chains, relayers, connections, and accounts are initialized.
loading...
UploadAndInstantiateContracts Subtest
Since contract upload and instantiation logic is inside s.Run
, we define variables for the instantiated contracts outside of the s.Run
method to use them in the subsequent subtests.
loading...
Best Practice: Storing Instantiated Contracts
Although here we are storing the instantiated contracts in variables, it is advisable to store them in the ContractTestSuite
struct to make them accessible to all test functions. It might also be helpful to move contract upload and instantiation logic to the ContractTestSuite
's SetupTest
method.
This is what is done in the cw-ica-controller
's actual test suite. There are a lot of test functions there, which is also a good reference for writing custom tests.
loading...
Then we open a subtest to upload and instantiate both the cw-ica-controller
and callback-counter
contracts. We first upload the callback-counter
contract:
loading...
Then we instantiate the callback-counter
contract:
loading...
Notice that the callback-counter
takes no arguments in its instantiation.
Then we upload and instantiate the cw-ica-controller
contract:
loading...
Channel Open Init on Instantiate
Recall that the cw-ica-controller
initiates the channel opening handshake upon its instantiation. This is why we wait for 5 blocks after the instantiation to ensure that the handshake is completed.
loading...
Verify_ChannelOpenHandshake Subtest
The next subtest is a set of assertions to ensure that the interchain account was created successfully:
loading...
Best Practice: gRPC Query Client
Notice the use of the autogenerated query client for both the cw-ica-controller
and callback-counter
contracts. This is the recommended way to query the contracts although you can also use the .Query
method on the contract instance.
loading...
Test_CosmosMsg_Delegate Subtest
In the next subtest, we fund the interchain account and stake some tokens with it. We fund the interchain account using the s.FundAddressChainB
method, which can be found in e2e/interchaintestv8/e2esuite/utils.go
.
loading...
Next, we construct the execute message to stake tokens with the interchain account:
loading...
Then we use the contract.Execute
method to execute the message, and we wait for 5 blocks to ensure that the IBC packet lifecycle is completed:
loading...
The rest of the subtest is a set of assertions to ensure that the delegation was successful:
loading...
Thank you for reading this tutorial. I hope you found it helpful.