mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-28 12:32:37 +03:00
Merge pull request #818 from fitzgen/guide-wasm-bindgen-test
guide: Add documentation for testing with `wasm-bindgen-test`
This commit is contained in:
commit
c6ede65856
@ -1,167 +1,7 @@
|
||||
# `wasm-bindgen-test`
|
||||
|
||||
This crate is an experimental test harness for `wasm32-unknown-unknown`, with
|
||||
the goal of allowing you to write tests as you normally do in Rust and then
|
||||
simply:
|
||||
|
||||
```
|
||||
cargo test --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
This project is still in the early stages of its development so there's not a
|
||||
ton of documentation just yet, but a taste of how it works is:
|
||||
|
||||
* First, install the test runner.
|
||||
|
||||
```
|
||||
cargo install --path crates/cli
|
||||
```
|
||||
|
||||
(this comes with the normal `wasm-bindgen` CLI tool
|
||||
|
||||
* Next, add this to your `.cargo/config`:
|
||||
|
||||
```toml
|
||||
[target.wasm32-unknown-unknown]
|
||||
runner = 'wasm-bindgen-test-runner'
|
||||
```
|
||||
|
||||
* Next, configure your project's dev-dependencies:
|
||||
|
||||
```toml
|
||||
[dev-dependencies]
|
||||
# or [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = { git = 'https://github.com/rustwasm/wasm-bindgen' }
|
||||
```
|
||||
|
||||
* Next, write some tests!
|
||||
|
||||
```rust
|
||||
// in tests/wasm.rs
|
||||
extern crate wasm_bindgen_test;
|
||||
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn pass() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn fail() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
```
|
||||
|
||||
* And finally, execute your tests:
|
||||
|
||||
```
|
||||
$ cargo test --target wasm32-unknown-unknown
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 0.11s
|
||||
Running /home/.../target/wasm32-unknown-unknown/debug/deps/wasm-4a309ffe6ad80503.wasm
|
||||
running 2 tests
|
||||
|
||||
test wasm::pass ... ok
|
||||
test wasm::fail ... FAILED
|
||||
|
||||
failures:
|
||||
|
||||
---- wasm::fail output ----
|
||||
error output:
|
||||
panicked at 'assertion failed: `(left == right)`
|
||||
left: `1`,
|
||||
right: `2`', crates/test/tests/wasm.rs:14:5
|
||||
|
||||
JS exception that was thrown:
|
||||
RuntimeError: unreachable
|
||||
at __rust_start_panic (wasm-function[1362]:33)
|
||||
at rust_panic (wasm-function[1357]:30)
|
||||
at std::panicking::rust_panic_with_hook::h56e5e464b0e7fc22 (wasm-function[1352]:444)
|
||||
at std::panicking::continue_panic_fmt::had70ba48785b9a8f (wasm-function[1350]:122)
|
||||
at std::panicking::begin_panic_fmt::h991e7d1ca9bf9c0c (wasm-function[1351]:95)
|
||||
at wasm::fail::ha4c23c69dfa0eea9 (wasm-function[88]:477)
|
||||
at core::ops::function::FnOnce::call_once::h633718dad359559a (wasm-function[21]:22)
|
||||
at wasm_bindgen_test::__rt::Context::execute::h2f669104986475eb (wasm-function[13]:291)
|
||||
at __wbg_test_fail_1 (wasm-function[87]:57)
|
||||
at module.exports.__wbg_apply_2ba774592c5223a7 (/home/alex/code/wasm-bindgen/target/wasm32-unknown-unknown/wbg-tmp/wasm-4a309ffe6ad80503.js:61:66)
|
||||
|
||||
|
||||
failures:
|
||||
|
||||
wasm::fail
|
||||
|
||||
test result: FAILED. 1 passed; 1 failed; 0 ignored
|
||||
|
||||
error: test failed, to rerun pass '--test wasm'
|
||||
```
|
||||
|
||||
And that's it! You've now got a test harness executing native wasm code inside
|
||||
of Node.js and you can use `cargo test` as you normally would for workflows.
|
||||
|
||||
## Asynchronous Tests
|
||||
|
||||
Not all tests can execute immediately and some may need to do "blocking" work
|
||||
like fetching resources and/or other bits and pieces. To accommodate this
|
||||
asynchronous tests are also supported through the `futures` crate:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen_test(async)]
|
||||
fn my_test() -> impl Future<Item = (), Error = JsValue> {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The test will pass if the future resolves without panicking or returning an
|
||||
error, and otherwise the test will fail.
|
||||
|
||||
This support is currently powered by the `wasm-bindgen-futures` crate.
|
||||
|
||||
## Running Tests in Headless Browsers
|
||||
|
||||
Add this to the root of your test crate:
|
||||
|
||||
```rust
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
```
|
||||
|
||||
### Configuring Which Browser is Used
|
||||
|
||||
If one of the following environment variables is set, then the corresponding
|
||||
WebDriver and browser will be used. If none of these environment variables are
|
||||
set, then the `$PATH` is searched for a suitable WebDriver implementation.
|
||||
|
||||
#### `GECKODRIVER=path/to/geckodriver`
|
||||
|
||||
Use Firefox for headless browser testing, and `geckodriver` as its
|
||||
WebDriver.
|
||||
|
||||
The `firefox` binary must be on your `$PATH`.
|
||||
|
||||
[Get `geckodriver` here](https://github.com/mozilla/geckodriver/releases)
|
||||
|
||||
#### `CHROMEDRIVER=path/to/chromedriver`
|
||||
|
||||
Use Chrome for headless browser testing, and `chromedriver` as its
|
||||
WebDriver.
|
||||
|
||||
The `chrome` binary must be on your `$PATH`.
|
||||
|
||||
[Get `chromedriver` here](http://chromedriver.chromium.org/downloads)
|
||||
|
||||
#### `SAFARIDRIVER=path/to/safaridriver`
|
||||
|
||||
Use Safari for headless browser testing, and `safaridriver` as its
|
||||
WebDriver.
|
||||
|
||||
This is installed by default on Mac OS. It should be able to find your Safari
|
||||
installation by default.
|
||||
|
||||
### Debugging Headless Browser Tests
|
||||
|
||||
Set the `NO_HEADLESS=1` environment variable and the browser tests will not run
|
||||
headless. Instead, the tests will start a local server that you can visit in
|
||||
your Web browser of choices, and headless testing should not be used. You can
|
||||
then use your browser's devtools to debug.
|
||||
[**Read the "Testing with `wasm-bindgen-test`" section of the
|
||||
guide!**](https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/index.html)
|
||||
|
||||
## Components
|
||||
|
||||
|
@ -64,7 +64,15 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
- [Contributing](./contributing/index.md)
|
||||
- [Testing with `wasm-bindgen-test`](./wasm-bindgen-test/index.md)
|
||||
- [Usage](./wasm-bindgen-test/usage.md)
|
||||
- [Writing Asynchronous Tests](./wasm-bindgen-test/asynchronous-tests.md)
|
||||
- [Testing in Headless Browsers](./wasm-bindgen-test/browsers.md)
|
||||
- [Continuous Integration](./wasm-bindgen-test/continuous-integration.md)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
- [Contributing to `wasm-bindgen`](./contributing/index.md)
|
||||
- [Testing](./contributing/testing.md)
|
||||
- [Internal Design](./contributing/design/index.md)
|
||||
- [JS Objects in Rust](./contributing/design/js-objects-in-rust.md)
|
||||
|
41
guide/src/wasm-bindgen-test/asynchronous-tests.md
Normal file
41
guide/src/wasm-bindgen-test/asynchronous-tests.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Writing Asynchronous Tests
|
||||
|
||||
Not all tests can execute immediately and some may need to do "blocking" work
|
||||
like fetching resources and/or other bits and pieces. To accommodate this
|
||||
asynchronous tests are also supported through the `futures` and
|
||||
`wasm-bindgen-futures` crates.
|
||||
|
||||
To write an asynchronous test:
|
||||
|
||||
1. Change `#[wasm_bindgen_test]` into `#[wasm_bindgen_test(async)]`
|
||||
|
||||
2. Change the return type of the test function to `impl Future<Item = (), Error
|
||||
= JsValue>`
|
||||
|
||||
The test will pass if the future resolves without panicking or returning an
|
||||
error, and otherwise the test will fail.
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
extern crate futures;
|
||||
extern crate js_sys;
|
||||
extern crate wasm_bindgen_futures;
|
||||
|
||||
use futures::Future;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
#[wasm_bindgen_test(async)]
|
||||
fn my_async_test() -> impl Future<Item = (), Error = JsValue> {
|
||||
// Create a promise that is ready on the next tick of the micro task queue.
|
||||
let promise = js_sys::Promise::resolve(&JsValue::from(42));
|
||||
|
||||
// Convert that promise into a future and make the test wait on it.
|
||||
JsFuture::from(promise)
|
||||
.map(|x| {
|
||||
assert_eq!(x, 42);
|
||||
})
|
||||
.map_err(|_| unreachable!())
|
||||
}
|
||||
```
|
71
guide/src/wasm-bindgen-test/browsers.md
Normal file
71
guide/src/wasm-bindgen-test/browsers.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Testing in Headless Browsers
|
||||
|
||||
## Configure Your Test Crate
|
||||
|
||||
Add this to the root of your test crate, e.g. `$MY_CRATE/tests/wasm.rs`:
|
||||
|
||||
```rust
|
||||
use wasm_bindgen_test::wasm_bindgen_test_configure;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
```
|
||||
|
||||
## Configuring Which Browser is Used
|
||||
|
||||
> ⚡ If you are using `wasm-pack`, skip this step! Instead, use `wasm-pack test
|
||||
> --chrome`, `wasm-pack test --firefox`, or `wasm-pack test --safari`.
|
||||
> `wasm-pack` will automatically download and configure the appropriate
|
||||
> WebDriver client for you.
|
||||
|
||||
If one of the following environment variables is set, then the corresponding
|
||||
WebDriver and browser will be used. If none of these environment variables are
|
||||
set, then the `$PATH` is searched for a suitable WebDriver implementation.
|
||||
|
||||
#### `GECKODRIVER=path/to/geckodriver`
|
||||
|
||||
Use Firefox for headless browser testing, and `geckodriver` as its
|
||||
WebDriver.
|
||||
|
||||
The `firefox` binary must be on your `$PATH`.
|
||||
|
||||
[Get `geckodriver` here](https://github.com/mozilla/geckodriver/releases)
|
||||
|
||||
#### `CHROMEDRIVER=path/to/chromedriver`
|
||||
|
||||
Use Chrome for headless browser testing, and `chromedriver` as its
|
||||
WebDriver.
|
||||
|
||||
The `chrome` binary must be on your `$PATH`.
|
||||
|
||||
[Get `chromedriver` here](http://chromedriver.chromium.org/downloads)
|
||||
|
||||
#### `SAFARIDRIVER=path/to/safaridriver`
|
||||
|
||||
Use Safari for headless browser testing, and `safaridriver` as its
|
||||
WebDriver.
|
||||
|
||||
This is installed by default on Mac OS. It should be able to find your Safari
|
||||
installation by default.
|
||||
|
||||
## Running the Tests in the Headless Browser
|
||||
|
||||
Once the tests are configured to run in a headless browser, executing the tests
|
||||
is the same:
|
||||
|
||||
```bash
|
||||
cargo test --target wasm32-unknown-unknown
|
||||
|
||||
# or, if you're using wasm-pack
|
||||
wasm-pack test --headless --chrome --firefox --safari
|
||||
```
|
||||
|
||||
### Debugging Headless Browser Tests
|
||||
|
||||
> If you're using `wasm-pack`, omitting the `--headless` flag will disable
|
||||
> headless mode, and allow you to debug failing tests in your browser's
|
||||
> devtools.
|
||||
|
||||
Set the `NO_HEADLESS=1` environment variable and the browser tests will not run
|
||||
headless. Instead, the tests will start a local server that you can visit in
|
||||
your Web browser of choices, and headless testing should not be used. You can
|
||||
then use your browser's devtools to debug.
|
63
guide/src/wasm-bindgen-test/continuous-integration.md
Normal file
63
guide/src/wasm-bindgen-test/continuous-integration.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Setting Up Continuous Integration with `wasm-bindgen-test`
|
||||
|
||||
This page contains example configurations for running `wasm-bindgen-test`-based
|
||||
tests in various CI services.
|
||||
|
||||
Is your favorite CI service missing? [Send us a pull
|
||||
request!](https://github.com/rustwasm/wasm-bindgen)
|
||||
|
||||
## Travis CI
|
||||
|
||||
```yaml
|
||||
language: rust
|
||||
rust: nightly
|
||||
|
||||
addons:
|
||||
firefox: latest
|
||||
chrome: stable
|
||||
|
||||
install:
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
- cargo install wasm-bindgen-cli
|
||||
# Install node.js with nvm.
|
||||
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
|
||||
- source ~/.nvm/nvm.sh
|
||||
- nvm install v10.5
|
||||
# Install chromedriver.
|
||||
- curl --retry 5 -LO https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip
|
||||
- unzip chromedriver_linux64.zip
|
||||
# Install geckodriver.
|
||||
- curl --retry 5 -LO https://github.com/mozilla/geckodriver/releases/download/v0.21.0/geckodriver-v0.21.0-linux64.tar.gz
|
||||
- tar xf geckodriver-v0.21.0-linux64.tar.gz
|
||||
|
||||
script:
|
||||
# Test in Chrome.
|
||||
- CHROMEDRIVER=$(pwd)/chromedriver cargo test --target wasm32-unknown-unknown
|
||||
# Test in Firefox.
|
||||
- GECKODRIVER=$(pwd)/geckodriver cargo test --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
## AppVeyor
|
||||
|
||||
```yaml
|
||||
install:
|
||||
- ps: Install-Product node 10
|
||||
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
- cargo install wasm-bindgen-cli
|
||||
|
||||
build: false
|
||||
|
||||
test_script:
|
||||
# Test in Chrome. chromedriver is installed by default in appveyor.
|
||||
- set CHROMEDRIVER=C:\Tools\WebDriver\chromedriver.exe
|
||||
- cargo test --target wasm32-unknown-unknown
|
||||
- set CHROMEDRIVER=
|
||||
# Test in Firefox. geckodriver is also installed by default.
|
||||
- set GECKODRIVER=C:\Tools\WebDriver\geckodriver.exe
|
||||
- cargo test --target wasm32-unknown-unknown
|
||||
```
|
17
guide/src/wasm-bindgen-test/index.md
Normal file
17
guide/src/wasm-bindgen-test/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Testing on `wasm32-unknown-unknown` with `wasm-bindgen-test`
|
||||
|
||||
The `wasm-bindgen-test` crate is an experimental test harness for Rust programs
|
||||
compiled to wasm using `wasm-bindgen` and the `wasm32-unknown-unknown`
|
||||
target.
|
||||
|
||||
## Goals
|
||||
|
||||
* Write tests for wasm as similar as possible to how you normally would write
|
||||
`#[test]`-style unit tests for native targets.
|
||||
|
||||
* Run the tests with the usual `cargo test` command but with an explicit wasm
|
||||
target:
|
||||
|
||||
```
|
||||
cargo test --target wasm32-unknown-unknown
|
||||
```
|
110
guide/src/wasm-bindgen-test/usage.md
Normal file
110
guide/src/wasm-bindgen-test/usage.md
Normal file
@ -0,0 +1,110 @@
|
||||
# Using `wasm-bindgen-test`
|
||||
|
||||
## Install the Test Runner
|
||||
|
||||
> ⚡ If you are using `wasm-pack`, skip this step! `wasm-pack test` will
|
||||
> automatically ensure that the right version of the test runner is installed.
|
||||
|
||||
The test runner comes along with the main `wasm-bindgen` CLI tool. Make sure to
|
||||
replace "X.Y.Z" with the same version of `wasm-bindgen` that you already have in
|
||||
`Cargo.toml`!
|
||||
|
||||
```shell
|
||||
cargo install wasm-bindgen-cli --vers "X.Y.Z"
|
||||
```
|
||||
|
||||
## Configure `.cargo/config` to use the Test Runner
|
||||
|
||||
> ⚡ If you are using `wasm-pack`, skip this step! `wasm-pack test` will
|
||||
> automatically configure `cargo test` to use the `wasm-bindgen` test runner.
|
||||
|
||||
Add this to `$MY_CRATE/.cargo/config`:
|
||||
|
||||
```toml
|
||||
[target.wasm32-unknown-unknown]
|
||||
runner = 'wasm-bindgen-test-runner'
|
||||
```
|
||||
|
||||
## Add `wasm-bindgen-test` to Your `Cargo.toml`'s `[dev-dependencies]`
|
||||
|
||||
Make sure to replace "X.Y.Z" with the same version of `wasm-bindgen` that you
|
||||
have in the `[dependencies]` section!
|
||||
|
||||
```toml
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "X.Y.Z"
|
||||
```
|
||||
|
||||
## Write Some Tests
|
||||
|
||||
Create a `$MY_CRATE/tests/wasm.rs` file:
|
||||
|
||||
```rust
|
||||
extern crate wasm_bindgen_test;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn pass() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn fail() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
```
|
||||
|
||||
Writing tests is the same as normal Rust `#[test]`s, except we are using the
|
||||
`#[wasm_bindgen_test]` attribute.
|
||||
|
||||
One other difference is that the tests **must** be in the root of the crate, or
|
||||
within a `pub mod`. Putting them inside a private module will not work.
|
||||
|
||||
## Execute Your Tests
|
||||
|
||||
> ⚡ If you are using `wasm-pack`, run `wasm-pack test` instead! For more
|
||||
> details, run `wasm-pack test --help`.
|
||||
|
||||
Run the tests by specifying the `wasm32-unknown-unknown` target when running
|
||||
`cargo test`. By default, the tests are run in Node.js, but you can [configure
|
||||
tests to run inside headless browsers](./browsers.html) as well.
|
||||
|
||||
```shell
|
||||
$ cargo test --target wasm32-unknown-unknown
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 0.11s
|
||||
Running /home/.../target/wasm32-unknown-unknown/debug/deps/wasm-4a309ffe6ad80503.wasm
|
||||
running 2 tests
|
||||
|
||||
test wasm::pass ... ok
|
||||
test wasm::fail ... FAILED
|
||||
|
||||
failures:
|
||||
|
||||
---- wasm::fail output ----
|
||||
error output:
|
||||
panicked at 'assertion failed: `(left == right)`
|
||||
left: `1`,
|
||||
right: `2`', crates/test/tests/wasm.rs:14:5
|
||||
|
||||
JS exception that was thrown:
|
||||
RuntimeError: unreachable
|
||||
at __rust_start_panic (wasm-function[1362]:33)
|
||||
at rust_panic (wasm-function[1357]:30)
|
||||
at std::panicking::rust_panic_with_hook::h56e5e464b0e7fc22 (wasm-function[1352]:444)
|
||||
at std::panicking::continue_panic_fmt::had70ba48785b9a8f (wasm-function[1350]:122)
|
||||
at std::panicking::begin_panic_fmt::h991e7d1ca9bf9c0c (wasm-function[1351]:95)
|
||||
at wasm::fail::ha4c23c69dfa0eea9 (wasm-function[88]:477)
|
||||
at core::ops::function::FnOnce::call_once::h633718dad359559a (wasm-function[21]:22)
|
||||
at wasm_bindgen_test::__rt::Context::execute::h2f669104986475eb (wasm-function[13]:291)
|
||||
at __wbg_test_fail_1 (wasm-function[87]:57)
|
||||
at module.exports.__wbg_apply_2ba774592c5223a7 (/home/alex/code/wasm-bindgen/target/wasm32-unknown-unknown/wbg-tmp/wasm-4a309ffe6ad80503.js:61:66)
|
||||
|
||||
|
||||
failures:
|
||||
|
||||
wasm::fail
|
||||
|
||||
test result: FAILED. 1 passed; 1 failed; 0 ignored
|
||||
|
||||
error: test failed, to rerun pass '--test wasm'
|
||||
```
|
Loading…
Reference in New Issue
Block a user