
The Design and Use of QuickCheck - begriffs
https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html?hn=1
======
tmoertel
One of my favorite examples of property-based testing is in the docs for
Haskell's Text.ParserCombinators.ReadP module. The semantics of the
combinators are succinctly (but fully) documented in the form of QuickCheck
properties.

[https://hackage.haskell.org/package/base-4.9.1.0/docs/Text-P...](https://hackage.haskell.org/package/base-4.9.1.0/docs/Text-
ParserCombinators-ReadP.html)

------
moomin
The first line sounds like hubris, but amazingly it's actually true.
QuickCheck makes extremely good (not over-complex or 'clever') use of return
type polymorphism and applicatives.

Property testing is a good idea in any language, but its particularly elegant
in Haskell.

------
davnn
Also: it's the coolest example of type classes Simon Peyton Jones knows and he
explains why here (around 34-35 min):

[https://youtu.be/6COvD8oynmI](https://youtu.be/6COvD8oynmI)

------
k__
This seems to be the way to go for testing.

I've wanted to use it for my current React-Native project. I found a JS
implementation AND a babel plugin that creates the tests from flow-types.

The question for me here is, how long does this take compared to regular
testing? I read people complained about AVA because of bad test performance
(it does many parallel tests).

Also, where to put it in the chain?

Should I put it pre-push, pre-build, somewhere in the CI?

~~~
mukeshsoni
Can you please provide the link to the babel plugin which creates the random
values from flow types?

~~~
scriptdevil
Very likely this: [http://github.com/unbounce/babel-plugin-transform-flow-to-
ge...](http://github.com/unbounce/babel-plugin-transform-flow-to-gen)

[https://medium.com/@gabescholz/randomized-testing-in-
javascr...](https://medium.com/@gabescholz/randomized-testing-in-javascript-
without-lifting-a-finger-8d616d7048af)

------
lacampbell
Has anyone here converted from 'regular' unit testing to quickcheck, or other
property-based unit testing libraries? I'm wondering if it's worth taking the
time out to learn, but I have my reservations regarding non-deterministic
testing.

~~~
nshepperd
I never really understood the arguments against "non-deterministic" testing. A
property based test will check more cases, and therefore detect more bugs,
than the corresponding hand-chosen unit tests (in which you probably forgot at
least 2 of the important corner cases).

All determinism guarantees is that you'll either reliably detect a bug or
reliably not detect a bug, and hence get a nice aesthetic line of green
checkmarks followed by red crosses in your test history. Or just get a nice
looking line of green and not even know the bug is there. This seems like a
small thing to sacrifice to detect more bugs.

Of course, regular unit tests have their place too, when your specification
can't really be expressed as a "forall" property.

~~~
IanCal
> All determinism guarantees is that you'll either reliably detect a bug or
> reliably not detect a bug, and hence get a nice aesthetic line of green
> checkmarks followed by red crosses in your test history. Or just get a nice
> looking line of green and not even know the bug is there. This seems like a
> small thing to sacrifice to detect more bugs.

The situation you want to avoid is this:

Run tests, find bug.

Try and fix bug.

Rerun tests, tests pass.

Deploy fixes to production.

Later find out that the bug is not fixed, your second run of tests simply
didn't hit the right combination.

~~~
sethammons
We print the rand seed and allow tests to take a set seed. This allows us to
use random generated data and still have deterministic results for reproducing
failed cases.

~~~
IanCal
Yep, this is a really useful approach, and I highly recommend anyone here who
is thinking of trying this stuff out to take a note of the seed (or ensure
it's printed) as the first time you realise you want to do this it's often too
late!

------
frou_dh
In Go's standard library there is a basic QuickCheck facility. But apparently
it has only been imported by 20 opensource packages ever (see bottom of page):

[https://godoc.org/testing/quick](https://godoc.org/testing/quick)

~~~
sethammons
We've used it in at least one internal project. I found it to lessen
readability and make maintenance harder. It could be the way things were set
up. I like the basic idea, but that lib just wasn't doing it for me. We got
close to something usable with test case generators where you replaced the
intended bad value(s). There ended up being too much indirection for my taste
for too little reward.

------
tosh
You might also want to look into
[https://clojure.org/about/spec](https://clojure.org/about/spec)

