-
Notifications
You must be signed in to change notification settings - Fork 2
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
Some sort of feedback #2
Conversation
Since all NuGet Packages are checked in, I didn't want to run paket install, as this would produce a large diff. It should be done though in the next commit via: $ .paket/paket.bootstrapper.exe $ .paket/paket.exe install $ ./build.sh
I half expected you to do this 😉 It's interesting that, despite the cleaner API, Hedgehog-based test code bases are bigger than their FsCheck counterparts. It looks to me that this is because of its lack of reflection-based generators. Is that correct? |
It depends. If not writing shrinking functions for the (QuickCheck/FsCheck) arbitraries, then yes, Hedgehog-based test code bases can be bigger. On the other hand, Hedgehog's generators, and the Range DSL, provide fine-grained control over the scope and shrinking of generated values. In this case, the code bases can be smaller than their counterparts: /// A generator for random instants in time, expressed as
/// a date and time of day that shrinks towards year 2000.
let dateTime : Gen<DateTime> =
let yMin = DateTime.MinValue.Year
let yMax = DateTime.MaxValue.Year
gen {
let! y = Gen.integral <| Range.linearFrom 2015 yMin yMax
let! m = Gen.integral <| Range.constant 1 12
let! d = Gen.integral <| Range.constant 1 (DateTime.DaysInMonth (y, m))
let! h = Gen.integral <| Range.constant 0 23
let! n = Gen.integral <| Range.constant 0 59
let! s = Gen.integral <| Range.constant 0 59
return DateTime (y, m, d, h, n, s)
} That's a
There is no reflection-based generator, or even default generators (without taking a Range type), because I don't know how to make high-quality ones. @jystic shows how a bug slipped in bos/text library by using default arbitraries. It's on this video at 11:50 (up to 13:09). However, it is possible to write a reflection-based generator for F# Hedgehog using TypeShape, similar to this one, and it'll have shrinking integrated. (I'm not aware of something similar for the Haskell version of Hedgehog, but for QuickCheck, a high-quality generic arbitrary implementation is Li-yao Xia's generic-random library, from Brent Yorgey's post.) |
You could certainly build reflection-based generators on top of Hedgehog, as @moodmosaic points out, it's not clear what the defaults should be. Personally I always like to be explicit about the range and distribution of my test inputs, and that has come across in Hedgehog's design, but I can understand why people would also want something automatic that isn't as precise but is quicker / easier to use. |
I support the idea that explicit is better than implicit, so I'm not trying to convince anyone that it should be different. I do think, though, that Hedgehog could benefit from some sort of low-friction option for user data types. I'm aware of the TypeShape option for F#, although I haven't had time to familiarise myself with it. Eventually, I'll get to it, I hope. |
It may be easy to modify this example so that it works with Hedgehog's |
@ploeh, we've made some experiments with this here. We used TypeShape, so it's not reflection-based. This is not part of the F# Hedgehog library, and we may release it separately on NuGet to get feedback. (Development around this has been slow, as I'm more working with Haskell and C than .NET nowadays.) |
I was looking at the current implementation of
PollingConsumerProperties
, and I thought I could do a port, primarily for my own interest, to Hedgehog, in order to remove the noise from<!>
,<*>
,Arb.fromGen
andProp.forAll
, and fiddle with the automatic/integrated shrinking.Of course, this isn't perfect either; from 136 lines of code, it went to 155, and I'm positive that it might be introducing False Positives and/or False Negatives.
But I thought I'd share it with you anyway, in the form of a pull request, just in case you find it useful, and to provide some sort of feedback.
(Closing the pull request right away since the goal isn't to get this merged into
master
.)Since all NuGet Packages are checked in, I didn't want to run paket install, as this would produce a large diff. It should be done fairly easily though with something like:
# Assuming that `git clean -xdf` has run first. $ .paket/paket.bootstrapper.exe $ .paket/paket.exe install $ ./build.sh