Skip to content

docs: testing strategies guide#59

Merged
marc0olo merged 2 commits into
mainfrom
docs/guides-testing-strategies
Apr 16, 2026
Merged

docs: testing strategies guide#59
marc0olo merged 2 commits into
mainfrom
docs/guides-testing-strategies

Conversation

@marc0olo
Copy link
Copy Markdown
Member

Summary

  • Three-layer testing pyramid: unit tests → PocketIC integration → deployed testing
  • Rust unit testing via dependency injection (adapted from dfinity/examples)
  • Motoko unit testing with mops test
  • PocketIC integration testing in Rust with pocket_ic crate
  • Performance benchmarking with canbench
  • Containerized test networks with icp-cli Docker
  • Decision table mapping test scenarios to approaches

Sync recommendation

informed by dfinity/portal, dfinity/examples, dfinity/icp-cli

Cover the ICP canister testing pyramid: unit tests with dependency
injection (Rust), mops test (Motoko), PocketIC integration tests,
canbench performance benchmarking, and containerized test networks.
@marc0olo
Copy link
Copy Markdown
Member Author

Review: Testing Strategies

Must fix

  • Code fence missing language tag (line ~268): The canbench sample output block uses a bare ``` fence with no language tag. The build warns about this (guides/testing/strategies.md:260 — Code fence without language tag). Change to ```text or ```plain.

  • #[async_trait] on a sync-only trait: The StorageApi trait at the top of the Rust unit-testing section is annotated with #[async_trait] and imports async_trait::async_trait, but none of its methods are async. The annotation is harmless at compile time but adds a spurious dependency and signals to the reader that async methods are involved when none are. Either remove #[async_trait] and the import (if the goal is to show simple sync mocking), or add an async method to justify it. The downstream CanisterApi struct and test code are not affected since neither uses the attribute. The upstream example in .sources/examples/rust/unit_testable_rust_canister/ only applies async_trait to the async GovernanceApi trait — never to a sync one.

Suggestions

  • docs.rs/canbench-rs URL could be more specific: The link https://docs.rs/canbench-rs resolves but drops the user on the crate root without the module path. Following the project's own linking rule ("use https://docs.rs/<crate-name>/latest/<crate_name>/"), it should be https://docs.rs/canbench-rs/latest/canbench_rs/. Minor, but consistent with how other crate links are handled in this repo.

  • The icp.yaml example has a different environment block than the official guide: The page shows:

    environments:
      - name: test
        network: docker-test
        canisters: [backend]

    The official containerized-networks.md uses canisters: - my-canister (list syntax) rather than inline array syntax. Both are valid YAML, but using list syntax would be consistent with the upstream guide.

  • "Deployed testing" layer is missing a dedicated section: The pyramid lists docs: network overview concept page #3 as "Deployed testing — Test against a real network via the CLI or scripts", but the page has no ## Deployed testing section. The containerized networks section covers local networks, but the mainnet angle from the pyramid item is not addressed. Worth either clarifying that the containerized networks section covers this tier, or adding a sentence connecting it back to the pyramid.

Verified

  • All internal link targets exist: pocket-ic.md resolves to docs/guides/testing/pocket-ic.md; ../canister-management/lifecycle.md resolves to docs/guides/canister-management/lifecycle.mdx (Astro resolves .md links to .mdx); ../canister-management/logs.md resolves to docs/guides/canister-management/logs.md.
  • All icp CLI commands verified against .sources/icp-cli/docs/reference/cli.md: icp network start, icp network stop, icp network status --json, and icp deploy -e test are all valid commands with correct flags.
  • icp.yaml containerized network configuration (image, port-mapping, rm-on-exit) verified against .sources/icp-cli/docs/guides/containerized-networks.md — all fields are correct.
  • Instruction limit claim ("40 billion instructions per update call") verified against .sources/portal/docs/building-apps/canister-management/resource-limits.mdx — confirmed accurate.
  • candid_parser::utils::service_equal verified to exist at .sources/candid/rust/candid_parser/src/utils.rs:43.
  • pocket-ic = "9.0.2" version verified against .sources/examples/rust/unit_testable_rust_canister/src/hello_canister/Cargo.toml.
  • PocketIC API usage (PocketIcBuilder, create_canister, add_cycles, install_canister, update_call) verified against .sources/examples/rust/unit_testable_rust_canister/src/hello_canister/tests/integration_tests.rs and .sources/examples/rust/parallel_calls/src/multi_subnet/src/main.rs.
  • canbench setup, canbench.yml format, canbench_results.yml filename, and benchmark output all verified against .sources/portal/docs/building-apps/advanced/benchmarking.mdx and .sources/candid/.github/workflows/bench.yml.
  • Motoko mo:test package and import { test; suite; expect } "mo:test" syntax verified against .sources/motoko-core/test/ examples.
  • cargo test --lib command verified against .sources/examples/rust/unit_testable_rust_canister/README.md.
  • No dfx references. No banned URLs (no internetcomputer.org/docs or docs.internetcomputer.org). No .mdx or JSX in the .md file.
  • All code snippets are under 30 lines inline.
  • Content brief from stub is fully addressed: testing pyramid, unit testing (Rust + Motoko), PocketIC integration tests, performance benchmarking, containerized networks, and the "why testing matters on ICP" framing are all present.
  • Frontmatter is complete and consistent with the page body.
  • Build passes (npm run build — 86 pages built in 2.85s) with one expected warning for the missing language tag on the canbench output block.
  • <\!-- Upstream: --> comment is present at the end of the page.

@marc0olo
Copy link
Copy Markdown
Member Author

Feedback addressed:

  • Added text language tag to the bare canbench sample output code fence (resolves build warning)
  • Removed spurious #[async_trait] attribute and use async_trait::async_trait import from the sync-only StorageApi trait
  • Updated docs.rs/canbench-rs link to full path https://docs.rs/canbench-rs/latest/canbench_rs/
  • Added explicit connection in the "Containerized test networks" section intro linking it to the "Deployed testing" tier of the testing pyramid

@marc0olo marc0olo merged commit f80b935 into main Apr 16, 2026
1 check passed
@marc0olo marc0olo deleted the docs/guides-testing-strategies branch April 16, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant