← Back to Lessons Lesson 18 of 28
Intermediate getting-started
Testing Wasm
Why Test Wasm?
Rust/Wasm code runs in two environments — native (your machine) and browser (Wasm). Tests should cover both to catch environment-specific bugs.
Test Setup
# Cargo.toml
[dev-dependencies]
wasm-bindgen-test = "0.3"Unit Tests (Native)
Standard Rust tests run with cargo test:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
assert_eq!(add(-1, 1), 0);
assert_eq!(add(0, 0), 0);
}
#[test]
fn test_fibonacci() {
assert_eq!(fibonacci(0), 0);
assert_eq!(fibonacci(1), 1);
assert_eq!(fibonacci(10), 55);
}
}cargo testWasm Tests (Browser)
Tests that need browser APIs use wasm-bindgen-test:
#[cfg(test)]
mod wasm_tests {
use wasm_bindgen_test::*;
use super::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn test_greet() {
let result = greet("World");
assert_eq!(result, "Hello, World!");
}
#[wasm_bindgen_test]
fn test_dom_creation() {
let document = web_sys::window().unwrap().document().unwrap();
let el = document.create_element("div").unwrap();
el.set_text_content(Some("test"));
assert_eq!(el.text_content().unwrap(), "test");
}
}# Run in headless Chrome
wasm-pack test --headless --chrome
# Run in headless Firefox
wasm-pack test --headless --firefox
# Run in Node.js (no DOM available)
wasm-pack test --nodeAsync Tests
Test async Wasm functions:
#[wasm_bindgen_test]
async fn test_async_fetch() {
let window = web_sys::window().unwrap();
let resp = JsFuture::from(
window.fetch_with_str("/test-data.json")
).await.unwrap();
assert!(resp.is_object());
}Test Organization
src/
├── lib.rs # Your Wasm code
└── tests/ # Integration tests
├── native.rs # cargo test (no browser)
└── web.rs # wasm-pack test (needs browser)Testing Best Practices
| Practice | Why |
|---|---|
Test pure logic natively (cargo test) |
Fast, no browser needed |
Test DOM/browser interactions with wasm-bindgen-test |
Catches Wasm-specific issues |
Use --headless in CI |
No GUI needed on CI servers |
| Test error cases | Result::Err paths are often untested |
Benchmark with console.time() |
Catch performance regressions |
CI Configuration (GitHub Actions)
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: cargo-bins/cargo-binstall@main
- run: cargo binstall wasm-pack -y
- run: cargo test
- run: wasm-pack test --headless --chromeTry It
Click Run to see the test assertions pass. In real projects, these would be in #[test] and #[wasm_bindgen_test] functions.
Try It
Chapter Quiz
Pass all questions to complete this lesson