Today, we are excited to announce the official release of a new version of the Rust- and Python-PocketIC testing library alongside a new version of the PocketIC-Server.
PocketIC is a canister testing platform that supports deterministic, programmatic canister testing. It is lightweight and integrates seamlessly into existing testing infrastructure (e.g. cargo test). It runs as a standalone binary on MacOS and Linux without requiring additional containers or Virtual Machines. All that is required is that this binary be present on your host system.
Example:
use candid::{encode_one, Principal};
use pocket_ic::PocketIc;
#[test]
fn test_counter_canister() {
let pic = PocketIc::new();
// Create an empty canister as the anonymous principal.
let canister_id = pic.create_canister(None);
pic.add_cycles(canister_id, 1_000_000_000_000_000);
let wasm_bytes = load_counter_wasm(...);
pic.install_canister(canister_id, wasm_bytes, vec![], None);
// 'inc' is a counter canister method.
call_counter_canister(&pic, canister_id, "inc");
// Check if it had the desired effect.
let reply = call_counter_canister(&pic, canister_id, "read");
assert_eq!(reply, WasmResult::Reply(vec![0, 0, 0, 1]));
}
fn call_counter_canister(pic: &PocketIc, canister_id: Principal, method: &str) -> WasmResult {
pic.update_call(canister_id, Principal::anonymous(), method, encode_one(()).unwrap())
.expect("Failed to call counter canister")
}
In principle, it can support any programming language. It achieves that by providing a REST-API to interact with a subset of deterministic replica-components (the «Execution Environment»).
Our vision is that PocketIC replaces all current canister testing methods.
Why PocketIC?
- With PocketIC, test execution is reproducible, as non-deterministic components of the replica (such as consensus or networking) are replaced with deterministic counterparts.
- PocketIC allows for fast test execution, as networking related timeouts are removed.
- PocketIC is versatile and allows for more fine-grained control over the execution environment. For example, already today one can directly manipulate the stable memory of a canister and thus test canister upgrades.
What’s next?
Support for multiple subnets
The next big feature which is planned for November is support for multi-subnet testing: As a test author, you will be able to define a topology and test interaction between canisters installed on different subnets. Also, the cycles accounting should scale with the subnet size, similar to mainnet. In our estimate, this is useful in particular—but not only—for testing scenarios that involve the SNS.
HTTP Outcalls
As a test author, you will be able to mock HTTP-responses in a test. Thus, you can test scenarios involving HTTP-outcalls deterministically.
Minor Improvements & Optimizations
We are constantly on the lookout for ways to provide more power to the test author without hurting the consistency of the API. For example, in the current API every ingress message is executed in a separate block. In the future, we will provide an API that allows pooling ingress messages and executing them within a single block. This is not only closer to the scenario in production, but should also speed up tests.
Questions?
Reach out to us in the forum or leave a post here! We are happy to answer questions and help with the setup!