Q&A
前提
Rustでwasmのコードを自動テストするプログラムを作成しています。
wasm_bindgen_futures
クレートのspawn_local
メソッドに関するテストを作成している中、非同期処理にてうまく出力できない問題が発生しました。
実現したいこと
-
wasm_bindgen_futures::spawn_local
を使うコードの自動テストを実行できるようにする
発生している問題・エラーメッセージ
GitHubを用意しました。よろしければこちらからも確認できますので、参照お願いします。
https://github.com/kano1101/wasm_bindgen_futures_test
プロジェクトの構成
console
1% pwd 2/Users/a.kano/development/rust/github_crate/wasm_bindgen_futures_test 3% tree -L 2 . 4. 5|-- Cargo.toml 6|-- build_run.sh 7|-- build_test.sh 8|-- index.html 9|-- src 10| `-- main.rs 11`-- webdriver.json 12 131 directory, 6 files
Cargo.toml
toml
1[package] 2name = "wasm_bindgen_futures_test" 3version = "0.1.0" 4authors = ["Akira Kano <a.kano1101@gmail.com>"] 5edition = "2021" 6 7[dependencies] 8anyhow = "1.0.66" 9console_error_panic_hook = "0.1.7" 10log = "0.4.6" 11once_cell = "1.16.0" 12reqwest = { version = "0.11.13", default-features = false, features = ["json"] } 13serde = { version = "1.0.148", default-features = false, features = ["derive"] } 14tokio = { version = "1.22.0", default-features = false, features = ["sync"] } 15wasm-bindgen-futures = "0.4.33" 16wasm-bindgen-test = "0.3.33" 17wasm-logger = "0.2.0"
build_run.sh
bash
1( 2 cd `dirname $0` 3 cargo build --target wasm32-unknown-unknown 4 wasm-bindgen ./target/wasm32-unknown-unknown/debug/$(basename `pwd`).wasm --out-dir . --web 5 python -m http.server 8080 6)
build_test.sh
bash
1( 2 cd `dirname $0` 3 wasm-pack test --headless --firefox 4)
webdriver.json
json
1{ 2 "moz:firefoxOptions": { 3 "prefs": { 4 "media.navigator.streams.fake": true, 5 "media.navigator.permission.disabled": true 6 }, 7 "args": [] 8 } 9}
index.html
html
1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <h1>Testing now...</h1> 11 <script type="module"> 12 import init from "./wasm_bindgen_futures_test.js"; 13 14 init('./wasm_bindgen_futures_test_bg.wasm'); 15 </script> 16 </body> 17</html>
うまくいっているブラウザ動作について
下記コマンドを実行します。
console
1% ./build_run.sh 2 Finished dev [unoptimized + debuginfo] target(s) in 0.05s 3Serving HTTP on :: port 8080 (http://[::]:8080/) ...
その後、ブラウザでlocalhost:8080
にアクセスします。
上図のように、コンソールログにip.origin: XXX
が表示されています。
この出力から、プログラムが正しく動作していることが確認できました。
問題となっている自動テストについて
下記コマンドを実行します。
console
1% ./build_test.sh 2[INFO]: 🎯 Checking for the Wasm target... 3 Compiling wasm_bindgen_futures_test v0.1.0 (/Users/a.kano/development/rust/github_crate/wasm_bindgen_futures_test) 4 Finished dev [unoptimized + debuginfo] target(s) in 0.99s 5 Finished test [unoptimized + debuginfo] target(s) in 0.04s 6 Running unittests src/main.rs (target/wasm32-unknown-unknown/debug/deps/wasm_bindgen_futures_test-bd660ad6d6ccf035.wasm) 7Set timeout to 20 seconds... 8Running headless tests in Firefox on `http://127.0.0.1:55679/` 9Try find `webdriver.json` for configure browser's capabilities: 10Ok 11running 1 test 12 13test wasm_bindgen_futures_test::first_test ... ok 14 15test result: ok. 1 passed; 0 failed; 0 ignored 16console.log div contained: 17 %cDEBUG%c src/main.rs:101%c some debug log 18 color: white; padding: 0 3px; background: blue; 19 font-weight: bold; color: inherit 20 background: inherit; color: inherit 21 22console.log div contained: 23 %cERROR%c src/main.rs:104%c some error log 24 color: white; padding: 0 3px; background: darkred; 25 font-weight: bold; color: inherit 26 background: inherit; color: inherit
上記から、一見すると自動テスト自体はパスしているように見えます。
ただ、よく見るとどうやら目的とする処理に辿り着く前にプログラムが終了してしまっているようなのです。
なぜならうまくテストが実行されていれば、上記のログにip.origin: XXX
が出力されているはずです。
しかし、該当する出力は確認できないため、自動テストが意味を成していないことがわかります。
これが、今回の問題です!
私は、この非同期の終了を待ちたいです。どうすれば待つことができるでしょうか?
該当のソースコード
main.rs
rust
1use serde::Deserialize; 2#[derive(Deserialize)] 3struct Ip { 4 origin: String, 5} 6 7mod space { 8 use once_cell::sync::Lazy; 9 use tokio::sync::Mutex; 10 11 static INSTANCE: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None)); 12 13 pub async fn pull() -> anyhow::Result<()> { 14 use super::Ip; 15 let response = reqwest::get("http://httpbin.org/ip") 16 .await? 17 .json::<Ip>() 18 .await?; 19 let mut lock = INSTANCE.lock().await; 20 *lock = Some(response.origin); 21 Ok(()) 22 } 23 pub async fn get() -> Option<String> { 24 let lock = INSTANCE.lock().await; 25 lock.clone() 26 } 27} 28 29fn run() { 30 console_error_panic_hook::set_once(); 31 wasm_logger::init(wasm_logger::Config::default()); 32 33 log::trace!("some trace log"); 34 log::debug!("some debug log"); 35 log::info!("some info log"); 36 log::warn!("some warn log"); 37 log::error!("some error log"); 38 39 let fut = || async move { 40 assert!(space::get().await.is_none()); 41 assert!(space::pull().await.is_ok()); 42 let origin = space::get().await; 43 assert!(origin.is_some()); 44 log::debug!("ip.origin: {:?}", origin); 45 46 // 当然ですがコメントアウトを外すと、localhost:8080からの実行ではエラーになる 47 // しかし自動テストの方ではエラーにならない(処理が到達していないことがわかる) 48 // assert!(false); 49 }; 50 51 wasm_bindgen_futures::spawn_local(fut()); 52} 53 54fn main() { 55 run(); 56} 57 58use wasm_bindgen_test::wasm_bindgen_test; 59use wasm_bindgen_test::wasm_bindgen_test_configure; 60wasm_bindgen_test_configure!(run_in_browser); 61 62#[wasm_bindgen_test] 63async fn first_test() { 64 run(); 65}
補足情報(FW/ツールのバージョンなど)
console
1% zsh --version 2zsh 5.8.1 (x86_64-apple-darwin22.0) 3% python --version 4Python 3.11.0 5% wasm-pack --version 6wasm-pack 0.10.3 7% wasm-bindgen --version 8wasm-bindgen 0.2.83 9% cargo --version 10cargo 1.65.0 (4bc8f24d3 2022-10-20)
ブラウザはfirefoxを使っています。
解決方法ご存知の方、いらっしゃいましたらご教示のほどよろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2022/12/17 06:06