Attribute Macro test
#[test]
Expand description
Defines an End-to-End test.
The system requirements are:
- A Substrate node with
pallet-revive
installed on the local system. You can e.g. useink-node
and install it on your PATH, or provide a path to an executable using theCONTRACTS_NODE
environment variable.
Before the test function is invoked the contract will be built. Any errors that occur during the contract build will prevent the test function from being invoked.
§Header Arguments
The #[ink_e2e::test]
macro can be provided with additional arguments.
§Custom Environment
You can specify the usage of a custom environment:
#[ink_e2e::test(environment = crate::EnvironmentWithManyTopics)]
Our documentation contains an explainer of what custom environments are. For a full example see here.
§Custom Backend
You can switch the E2E test to use the DRink! testing framework with this syntax:
type E2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[ink_e2e::test(backend(runtime_only))]
async fn runtime_call_works() -> E2EResult<()> {
// ...
}
In this configuration the test will not run against a node that is running in the
background, but against an in-process slimmed down pallet-revive
execution
environment.
Please see the page on testing with DRink! in our documentation for more details. For a full example see here.
§Example
#[ink::contract]
mod my_module {
#[ink(storage)]
pub struct MyContract {}
impl MyContract {
#[ink(constructor)]
pub fn new() -> Self {
Self {}
}
#[ink(message)]
pub fn my_message(&self) {}
}
}
type E2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[ink_e2e::test]
async fn e2e_test(mut client: ::ink_e2e::Client<C, E>) -> E2EResult<()> {
// given
use my_module::MyContract;
let mut constructor = MyContract::new();
let contract = client
.instantiate("contract_transfer", &ink_e2e::bob(), &mut constructor)
.submit()
.await
.expect("instantiate failed");
let mut call_builder = contract.call_builder::<MyContract>();
// when
let my_message = call_builder.my_message();
let call_res = client
.call(&ink_e2e::eve(), &my_message)
.submit()
.await
.expect("call failed");
// then
assert!(call_res.is_ok());
Ok(())
}
You can also build the Keypair
type yourself, without going through
the pre-defined functions (ink_e2e::alice()
, …):
use std::str::FromStr;
let suri = ::ink_e2e::subxt_signer::SecretUri::from_str("//Alice").unwrap();
let alice = ::ink_e2e::Keypair::from_uri(&suri).unwrap();