Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested proptest!{}'s cause run time to rise exponentially #437

Open
target-san opened this issue Mar 28, 2024 · 2 comments
Open

Nested proptest!{}'s cause run time to rise exponentially #437

target-san opened this issue Mar 28, 2024 · 2 comments
Labels
help-request This issue is asking for advice/help on using proptest

Comments

@target-san
Copy link

target-san commented Mar 28, 2024

Due to how proptest!{ |(... stats ...)| { ...} } is implemented, it spawns new nested runner which in turn runs yet another num_cases. Thus, with default number of cases being 256, one nested proptest would do 65536 runs, and double nested one would do 16777216 (!!!) runs.

While I clearly understand why this happens, it was quite a surprise to me. I needed test which would perform nontrivial multistep initialization of certain engine, so I got 2 nested macros. And my test was running for like 246 seconds. When I replaced second nesting with smart-ish deduction of parameter I needed to generate, run time dropped from 246 to 3.7 seconds.

I see two problems here:

  1. Execution cost of nesting proptest! {} is IMO not articulated at all. Or I miss that warning completely.
  2. Doing whole multistage generation in parameters section, with all its composition, is quite cumbersome. Or, again, I missed that part completely.

Thoughts?

EDIT:
Maybe consider splitting proptest! macro into three? One creates outer runner and cannot be nested, another creates nested runner but does only single run (no exponent), third one behaves like old nested case?

@matthew-russo matthew-russo added the help-request This issue is asking for advice/help on using proptest label Mar 31, 2024
@matthew-russo
Copy link
Member

Thanks for reaching out, can you share an example of your tests? I don't think I have a good sense of what you're attempting to do

@target-san
Copy link
Author

Sorry for a bit messy initial description.

In general, my scenario is multi-stage data generation since ranges for some values depend on the state of object being initialized. Some observations so far:

  1. Chaining prop_flat_map is quite cumbersome and can easily bring debug output of object being initialized into scope. So I use nested proptest! {} blocks.
  2. Each proptest! {} block spawns separate TestRunner with default settings. Which is fine overall yet introduces nested run of multiple cases, 256 by default. As a result, with 1 nested block we get 65536 runs, with 2 - 16777216 (!) runs. This may be a bit unexpected. Maybe some kind of big WARNING in macro documentation is needed. I thought initially about additional macro which performs exactly 1 nested run but that may be unnecessary.
  3. Issue with cases number multiplication may be mitigated with Config::with_cases, although it's not very reliable. Configuration gets its values overridden by environment variables after it was created by user. Someone runs all this with PROPTEST_CASES=200 and you get back to almost square one. Maybe it's worth making Config read default values from env when it's created?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help-request This issue is asking for advice/help on using proptest
Projects
None yet
Development

No branches or pull requests

2 participants