#wasm32-unknown-unknown #testing #ignore #framework #test-framework #runtime-independent

macro webassembly-test

Runtime-independent wasm32-unknown-unknown test framework

1 unstable release

0.1.0 Jul 14, 2021

#1156 in WebAssembly

Download history 395/week @ 2024-07-20 227/week @ 2024-07-27 210/week @ 2024-08-03 172/week @ 2024-08-10 207/week @ 2024-08-17 279/week @ 2024-08-24 223/week @ 2024-08-31 359/week @ 2024-09-07 179/week @ 2024-09-14 289/week @ 2024-09-21 246/week @ 2024-09-28 318/week @ 2024-10-05 224/week @ 2024-10-12 170/week @ 2024-10-19 143/week @ 2024-10-26 158/week @ 2024-11-02

707 downloads per month

MIT/Apache

7KB

webassembly-test

This crate implements a cargo test support for wasm32-unknown-unknown target:

$ cat src/lib.rs
#[cfg(test)]
mod tests {
    use webassembly_test::webassembly_test;

    #[webassembly_test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }

    #[webassembly_test]
    fn it_does_not_work() {
        assert_eq!(2 + 2, 5);
    }

    #[webassembly_test]
    #[ignore]
    fn it_is_ignored() {
        assert_eq!(2 + 2, 5);
    }
}

$ cargo test --target wasm32-unknown-unknown
     Running `webassembly-test-runner target/wasm32-unknown-unknown/debug/deps/hello_world.wasm`

running 3 tests
test hello_world::tests::it_works ... ok
test hello_world::tests::it_does_not_work ... FAILED
test hello_world::tests::it_is_ignored ... ignored

test result: FAILED. 1 passed; 1 failed; 1 ignored;

webassembly-test is independent from any particular wasm runtime or environment. In fact, it is more of a pattern rather than a library, and can be easily adopted to a particular use-case.

MSRV: 1.54.0 (beta at the time of writing).

Writing Tests

When writing tests, use #[webassembly_test] rather than the usual #[test] macro. Add .cargo/config which sets a runner for wasm32-unknown-unknown:

[target.wasm32-unknown-unknown]
runner = "webassembly-test-runner"

Now, just cargo test --target wasm32-unknown-unknown will run the tests.

webassembly-test-runner is an example of a runner. You can install it with cargo install webassembly-test-runner. It uses wasmtime to run the tests in an empty environment. If the tested library needs environment-specific imports you need to write the runner yourself.

Example.

Implementing Your Own Runner

The webassembly_test macro is simple. For each test, it emits a corresponding wasm export with a name in special format. For the example, the names would be:

$webassembly-test$hello_world::tests::it_works
$webassembly-test$hello_world::tests::it_does_not_work
$webassembly-test$ignore$hello_world::tests::it_is_ignored

That is, $webassembly-test$ prefix, followed by ignore$, followed by the qualified name of the test function.

The test runner than loads a wasm modules, and calls all export which match the given format given format.

Example.

Implementation notes

webassembly_test uses concat!(module_path!(), #name) to set #[export_name] for test functions. The #[ignore] is encoded into a function name. Ideally, we'd use a custom wasm section to store the ignored attributes, but it seems impossible to correctly associate a custom section entry with full function name (proc macro doesn't have access to the module path of the function). Sample runner runs all the tests sequentially in a singe instance, but it should be possible to run tests in parallel in several instances.

Dependencies

~1.5MB
~37K SLoC