proptest-rs / proptest

Hypothesis-like property testing for Rust
Apache License 2.0
1.72k stars 160 forks source link

proptest! macro doesn't play nice with tokio::test #179

Open znewman01 opened 4 years ago

znewman01 commented 4 years ago

Hi! This is purely an ergonomics thing.

$ grep -E 'proptest|tokio' Cargo.toml
tokio = { version = "0.2.11", features = [ "macros", "signal" ] }
proptest = "0.9.4"
$ rustc --version
rustc 1.41.0 (5e1a79984 2020-01-27)

I'm working on some async-heavy code and like to use the tokio::test macro:

#[tokio::test]
async fn test_tokio() {
    assert_eq!(ready(()).await, ());
}

If I try to adapt it to the proptest context:

proptest! {
    #[tokio::test]
    async fn test_prop_tokio(byte in any::<u8>()) {
        assert_eq!(ready(byte).await, byte);
    }
}

I get some inscrutable errors:

error: expected one of `move`, `|`, or `||`, found keyword `fn`
  --> src/lib.rs:59:15
   |
59 |         async fn test_prop_tokio(byte in any::<u8>()) {
   |               ^^ expected one of `move`, `|`, or `||`

The following works around fine:

proptest! {
    #[test]
    fn test_prop(byte in any::<u8>()) {
        Runtime::new().unwrap().block_on(async {
            assert_eq!(ready(byte).await, byte);
        });
     }
}

(Using the proptest! macro with a closure doesn't, because it doesn't handle async closures.)

I think it'd be a little silly to special-case proptest for every test runner, but as I understand, the Tokio test macro pretty much just does my workaround.

I think the proptest! macro is very similar. I wonder if we could make one of the following changes:

IIRC custom test runner stuff is pretty in-flux right now, so maybe it's premature to do anything. Or I could be missing something obvious.

If you like any of these ideas or something similar, I might be able to take a stab at implementing, though I'm a little shaky on macros.

The above code assumes the following preamble:

use futures::future::ready;
use proptest::prelude::*;
use tokio::runtime::Runtime;

P.S. Thanks for your work on proptest; it's really helped me write high-assurance software and made testing fun to boot!

CAD97 commented 4 years ago

The root issue is that proptest! doesn't allow async fn. Adding async fn cases to the macro should make this "just work".

johnchildren commented 4 years ago

I would be interested in adding async support to the proptest macro, would it make sense to just add async versions of each case or have a separate proptest_async macro? I suppose it would be nice to be able to mix and match tests in the same usage.

Jannis commented 2 years ago

It would be great to have this!

matthew-russo commented 7 months ago

we'll be looking at async support holisitically in #442