la10736 / rstest

Fixture-based test framework for Rust
Apache License 2.0
1.21k stars 43 forks source link

Consider supporting `wasm-bindgen-test` for async test #211

Open FirelightFlagboy opened 1 year ago

FirelightFlagboy commented 1 year ago

Currently I've the following sample test that I would like to make it work using rstest and wasm_bindgen_test to be able to run in using wasm-pack test.

use wasm_bindgen_test::wasm_bindgen_test
use rstest::rstest;
use gloo_timers::future::sleep;
use std::time::Duration;

#[rstest]
#[case(200)]
#[case(100)]
#[wasm_bingen_test]
async fn test_sleep(#[case] duration: u32) {
    sleep(Duration::from_millis(duration).await
}

The problem

The test could not compile because it try to use async_std in this context which would not work with wasm-pack.

error[E0433]: failed to resolve: use of undeclared crate or module `async_std`
 --> [redacted]/tests/foo.rs:7:1
  |
7 | #[rstest]
  | ^^^^^^^^^ use of undeclared crate or module `async_std`
  |
  = note: this error originates in the attribute macro `rstest` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0433`.

Additional information

I've added the macro expansion using cargo-expand below (we can see the use of async_std):

cargo expand --test foo --target wasm32-unknown-unknown ```rust #![feature(prelude_import)] #![cfg(target_arch = "wasm32")] #[prelude_import] use std::prelude::rust_2021::*; #[macro_use] extern crate std; use gloo_timers::future::sleep; use rstest::rstest; use std::time::Duration; use wasm_bindgen_test::wasm_bindgen_test; #[cfg(test)] async fn test_sleep(duration: u32) { { sleep(Duration::from_millis(duration)).await; } } #[cfg(test)] mod test_sleep { use super::*; #[no_mangle] pub extern "C" fn __wbgt_case_1_0(cx: &::wasm_bindgen_test::__rt::Context) { let test_name = "foo::test_sleep::case_1"; cx.execute_async(test_name, case_1, None); } #[async_std::test] async fn case_1() { let duration = 200; test_sleep(duration).await } #[no_mangle] pub extern "C" fn __wbgt_case_2_1(cx: &::wasm_bindgen_test::__rt::Context) { let test_name = "foo::test_sleep::case_2"; cx.execute_async(test_name, case_2, None); } #[async_std::test] async fn case_2() { let duration = 100; test_sleep(duration).await } } #[rustc_main] #[no_coverage] pub fn main() -> () { extern crate test; test::test_main_static(&[]) } ```
la10736 commented 1 year ago

You're right. I'm working on wasm in the last moths and I meet this issue too.

Maybe I'll introduce this fix in the next release....

BTW I'm using the following workaround that I hope could work for you too

At crate level

#[cfg(test)]
pub(crate) mod wasm {
    use wasm_bindgen_test::wasm_bindgen_test as test;
}

Where you're writeing your tests

tests {
    use crate::wasm;

    #[rstest]
    #[wasm::test]
    async fn grpc_process(_init: ()) {
        ....
    }
}
la10736 commented 1 year ago

I forgot to mention the cause.... rstest accept only attribute where the last segment is test as test injected attribute.

FirelightFlagboy commented 1 year ago

Yes that's stated in inject test attribute

Just the attributes that ends with test (last path segment) can be injected: in this case the #[actix_rt::test] attribute will replace the standard #[test] attribute.