中級 getting-started

Wasmのテスト

なぜWasmをテストするのか?

Rust/Wasmコードはネイティブ(ローカルマシン)とブラウザ(Wasm)の2つの環境で動作します。環境固有のバグを検出するために、両方の環境でテストする必要があります。

テストのセットアップ

# Cargo.toml
[dev-dependencies]
wasm-bindgen-test = "0.3"

ユニットテスト(ネイティブ)

標準のRustテストは 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 test

Wasmテスト(ブラウザ)

ブラウザAPIを必要とするテストには 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");
    }
}
# ヘッドレスChromeで実行
wasm-pack test --headless --chrome

# ヘッドレスFirefoxで実行
wasm-pack test --headless --firefox

# Node.jsで実行(DOMは使用不可)
wasm-pack test --node

非同期テスト

非同期Wasm関数のテスト:

#[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());
}

テストの構成

src/
├── lib.rs          # Wasmコード
└── tests/          # 統合テスト
    ├── native.rs   # cargo test(ブラウザ不要)
    └── web.rs      # wasm-pack test(ブラウザ必要)

テストのベストプラクティス

プラクティス 理由
純粋なロジックはネイティブでテスト(cargo test 高速でブラウザ不要
DOM/ブラウザ操作は wasm-bindgen-test でテスト Wasm固有の問題を検出できる
CIでは --headless を使用 CIサーバーにGUIは不要
エラーケースもテスト Result::Err のパスはテストされないことが多い
console.time() でベンチマーク パフォーマンスの低下を検出できる

CI設定(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 --chrome

試してみよう

Run をクリックして、テストのアサーションが成功するのを確認してください。実際のプロジェクトでは、これらは #[test]#[wasm_bindgen_test] 関数内に記述します。

試してみる

チャプタークイズ

すべての問題に正解してレッスンを完了しましょう