webassembly-test 0.1.0

Runtime-independent wasm32-unknown-unknown test framework
Documentation
# webassembly-test

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

```console
$ 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`:

```toml
[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.](https://github.com/matklad/webassembly-test/tree/master/examples/hello-world/)

## 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:

```text
$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.](https://github.com/matklad/webassembly-test/tree/master/webassembly-test-runner/)

## 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.