-
Notifications
You must be signed in to change notification settings - Fork 30
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
When shrinking, try zero value first as a shortcut #223
Comments
When does Hedgehog give up? Is it after a certain number of shrinks? |
Unsure if that question was for me, but I have no idea. |
It was for whoever knows the answer ;) :P |
Are you talking about e.g. this? let myComplexGen =
gen {
let! a = Gen.int ...
let! b = Gen.string ...
return { A = a; B = b }
} If so, finding the simplest value for the record is simply to find the simplest value for the generators used when making it ( |
I don't think it is that simple though because you said
@moodmosaic said that Hedgehog (only) gives up after 100 discards, so since you are experiencing Hedgehog give up, your generator must include a filter. I think the behavior you want exists in the generator I created in #224 (since |
That can't be right. Here's a let dateTimeOffsetFrom21stCentury =
gen {
let min = DateTime(2000, 1, 1)
let max = DateTime(2100, 1, 1)
let center = DateTime.Now.Date
let! dt =
Gen.int64 (Range.exponentialFrom center.Ticks min.Ticks max.Ticks)
|> Gen.map DateTime
let! offset = Gen.int (Range.linearFrom 0 -11 11)
return DateTimeOffset(dt, TimeSpan.FromHours(float offset))
} Also, Hedgehog have given up before 100 shrinks (the test report says "after X tests and Y shrinks" where Y < 100; I can't remember ever seeing it report exactly 100 shrinks). |
I will try to reproduce |
Note that in my case, the test failure that caused the shrinking centered on DST changes. Sometimes it would shrink to some DST change in 2040 and thereabouts, whereas other times it would successfully shrink to the DST change closest to the current time. |
Hedgehog is hardcoded to give up after 100 discards... fsharp-hedgehog/src/Hedgehog/Property.fs Lines 153 to 156 in 81a7502
...and by default never gives up on shrinking. fsharp-hedgehog/src/Hedgehog/PropertyConfig.fs Lines 11 to 13 in 81a7502
@cmeeren, do you recall if your test changed this default shrink limit from However, my guess is that the shrink limit is not the issue. Especially since you said:
Hedgehog doesn't always find a smallest failing input. @cmeeren, do you recall what your test was that used that generator and didn't shrink to the smallest failing input as you expected? In the tests I added in the recent Hedgehog.Experimential PRs (1, 2, 3), I asserted that the shrunken input was always the minimum input that causes the test to fail. However, this is not possible in general. I am a bit knowledgeable about how Hedgehog does shrinking, so I know that Hedgehog will always find that minimum failing input (as long at the user code doesn't do something like mutation before the last My guess is that Hedgehog did try the minimal value, but it caused your test to pass. Then after finding a failing input, it shrunk until it got stuck in a "local optima" instead of finding the minimum failing input. |
Then I am thinking that we don't have enough information to investigate further. Ironically though, your description here is rather consistent with the behavior we are seeing in the draft PR hedgehogqa/fsharp-hedgehog-experimental#55. |
A test may have many generated values. These are potentially large and require many shrinks to get to the "simplest" value (e.g.
0
). Often, a test failure does not depend on many of the generated values. Still, I often experience these not being shrinked fully to the "simplest" value, because there's a lot to shrink and Hedgehog gives up shrinking after a while.This could be alleviated if Hedgehog, upon shrinking, first tested the "simplest" value of each generated parameter. If the test still fails, do this for the next, etc. If the test passes, revert and try the next parameter. After having "shortcutted" all possible parameters like this, which takes only as many shrinks as there are generated parameters, proceed with shrinking as normal. (This would also have the benefit of "saving" most of the shrinking capacity to the generated values that actually need proper shrinking.)
Am I making myself understood, or is my explanation hard to follow?
The text was updated successfully, but these errors were encountered: