Test for Motoko Canister

I’m looking for examples on how to test my Motoko canister. Could someone point me to some resources or share examples? Also, what is the recommended approach for testing Motoko canisters, especially with async methods?

Any guidance would be greatly appreciated. Thanks!

1 Like

For internal Motoko method testing/unit testing I would recommend Mops • Motoko Package Manager

For canister end to end testing it would recommend PocketIC
If you are using Javascript client then use 🧪 Announcing PicJS: TypeScript/JavaScript support for PocketIC!
other clients have different libraries

2 Likes

This is my current state of the art(not that it is art…but it works). Not a lot of deferred examples in here, but the basic setup should work with pic.js

If you want nns stuff you need to follow the pic.js hides for creating a reusable state.

1 Like

I tested the Mops package yesterday, but I could. not find any examples showing how to use it in a public canister method for example. I tried it, but I can’t see if the test is working ??

1 Like

This is my test:

import {test; suite } "mo:test/async";

import Principal "mo:base/Principal";
import Debug "mo:base/Debug";

import Sim "../backend_v1/main";

actor TestSim {

  public func runTests() : async () {
    var simInstance = await Sim.Sim();
    await suite("project suite", func() : async () {
      await test("addProject", func() : async () {

        let project = {
            bez = "bez";
            kbez = "kbez";
            desc = "desc";
            status = 1 : Nat8;
            createdAt = 1 : Int;
            createdBy = Principal.fromActor(TestSim);
            startDate = 2 : Int;
            endDate = 3 : Int;
        };
        let a = await simInstance.addProject(project);
        Debug.print("test");
        assert a == 2;
      });

    });
  }
}

The test is running and passed, but variable a does not have the value 2 and the test was still successful !

1 Like

This is now the working test:

import {test; suite } "mo:test/async";

import Principal "mo:base/Principal";
import Debug "mo:base/Debug";

import Sim "../backend_v1/main";

await suite("project suite", func() : async () {
  var simInstance = await Sim.Sim();
  await test("addProject", func() : async () {

    let project = {
        bez = "bez";
        kbez = "kbez";
        desc = "desc";
        status = 1 : Nat8;
        createdAt = 1 : Int;
        createdBy = Principal.fromText("4sd6s-xg3ws-aaulg-6h7ju-ntyrc-qpyot-lir4s-abk6o-4s5mn-s7jyv-tqe");
        startDate = 2 : Int;
        endDate = 3 : Int;
    };
    let a = await simInstance.addProject(project);
    Debug.print(debug_show(a));
    assert a == 0;
  });
});

With this test I can test the function itself.

When running a test with PocketIc, I encounter the following error:

Error from Canister lxzze-o7777-77777-aaaaa-cai: Canister’s Wasm module is not valid: Wasmtime failed to validate wasm module wasmtime::Module::validate() failed with memory64 must be enabled for 64-bit memories (at offset 0x5d5).

This is likely an error with the compiler/CDK toolchain being used to build the canister. Please report the error to IC devs on the forum: https://forum.dfinity.org and include which language/CDK was used to create the canister.

I use Motoko: base = “0.13.7” on Mac.

removing actor name should enable replica test mode in mops:

- actor TestSim {
+ actor {

or add first line to your test code:

// @testmode replica

Specifying pocket-ic in mops.toml will speed up replica tests

[toolchain]
pocket-ic = "4.0.0"

Use --reporter verbose to see each suite/test name and Debug.print messages

This type of tests(interpreter mode) is the fastest. If you need cycles, timers, canister upgrades, you can simply wrap it to run in a replica:

actor {
  public func runTests() : async () {
    // your tests here
  };
};

Looks like you are testing out 64 bit?

@NathanosDev does pic.js have a way to enable 64-bit yet?

not intentionally !!

1 Like