IBC Application Testing

One of the hardest steps in building an interchain application is testing. Due to the complexity of IBC and Cosmos SDK chains there are some trade-offs to consider in your approach to testing.

Testing Tools

This page aims to provide you with a high-level overview of the available testing tools and how to use them. That way you can make an informed decision on which tool is best for your application’s needs.

Mock IBC Testing

The easiest way to test your CosmWasm IBC application is by using cw-orchestrator’s mock IBC environment. This testing environment allows you to connect multiple Mock instances over a virtual IBC connection. Relaying is simulated and you can test your application’s IBC logic without needing to deploy it to a live chain.

Type: MockBech32Interchain

Advantages:

  • Easy to set up and use.
  • Very fast to execute.
  • Easily configurable.

Disadvantages:

  • Does not support custom Cosmos SDK modules.
  • Not end-to-end.
  • Can’t make use of existing on-chain infrastructure.

Starship

Starship is a kubernetes-based Cosmos SDK environment spawner. It allows you to spin up multiple Cosmos SDK blockchain networks and connect them together. It includes a relayer, faucet and block explorer. Allowing you to test your application in a more realistic environment.

Type: Starship

Advantages:

  • Access to Cosmos SDK modules from your smart contract.
  • End-to-end testing.
  • Can be made available for front-end testing.

Disadvantages:

  • Slow to execute.
  • Requires more setup and knowledge to use.
  • Can only run for limited time due to resource constraints.

Testnet

Type: DaemonInterchain

The final option is to deploy your application to a testnet. Doing this will ensure your application is tested in a real-world environment and makes it possible to start sharing what you’ve built with others. However, this approach is the most time-consuming and requires the most setup.

Advantages:

  • Real-world testing.
  • Can be shared with others.
  • Can be used for marketing purposes.

Disadvantages:

  • Slow to execute.
  • Requires running your own relayer (or partnering with a relayer service).
  • Testnets are often unstable.

Tooling Conclusion

Before you start testing your application, consider the trade-offs between the different testing environments. For most applications, using the mock IBC environment is the best choice. However, if you need to test your application with custom Cosmos SDK modules, you should consider using Starship. Finally, if you’re ready to share your application with the world, deploying to a testnet is the way to go.

Testing Abstract Apps

We’ve created helpers for you to test your Abstract App in any of the aforementioned environments. The rest of this page will show you how to use them.

We’ll be using the abstract-client crated which we covered in our section on testing. This crate includes a AbstractInterchainClient type that can be used to deploy and load abstract’s infrastructure to any of the testing environments.

Local & Mock Environments

For local and mock environments we provide the AbstractInterchainClient::deploy_on function. This function can take a MockBech32Interchain or Starship argument and it will deploy the Abstract contracts to the environment and set up the necessary IBC connections.

#![allow(unused)]
fn main() {
let interchain = MockBech32InterchainEnv::new(
        vec![("juno-1", "juno"), ("osmosis-1", "osmo")],
    );
let abstract_interchain = AbstractInterchainClient::deploy_on(&interchain);
// single-chain client
let juno_abstract: AbstractClient = abstract_interchain.client("juno-1");
}

Testnet/Mainnet Environments

Abstract maintains deployments for a few testnets and for most mainnets. Instead of re-deploying Abstract to these networks you can make use of the load_from function on AbstractInterchainClient. To do this, first construct an InterchainDaemon object with the chains you’d like to use.

#![allow(unused)]
fn main() {
let interchain = DaemonInterchain::new(vec![
        (LOCAL_JUNO, None),
        (LOCAL_OSMO, None)
    ], &ChannelCreationValidator)?;

let abstract_interchain = AbstractInterchainClient::load_from(&interchain);
// single-chain client
let juno_abstract: AbstractClient = abstract_interchain.client("juno-1");
}