nick8325 / quickcheck

Automatic testing of Haskell programs.
Other
713 stars 119 forks source link

Full number of tests when testing a constant containing .&&. and friends. #309

Closed 1chb closed 5 months ago

1chb commented 4 years ago

QuickCheck-2.14.1

GHCi, version 8.4.3: -- also tested version 8.6.5
Loaded GHCi configuration from ...
λ> import Test.QuickCheck
λ> quickCheck $ True && True
+++ OK, passed 1 test.
λ> quickCheck $ True .&&. True
+++ OK, passed 100 tests.

When testing a property without parameters, QuickCheck is kind enough to run only one test. But not if the property contains the (.&&.) combinator. Same for (.||.) and (.&.).

This might seem to be a stupid use case but I often fully apply a property with a counterexample that QuickCheck found, to be able to investigate what went wrong with that particular case. Sometimes I even add trace calls in my code to see what happens. That does not work well when running 100 instances... But no worry, a working workaround is to explicitly set maxSuccess=1.

imuli commented 2 years ago

This appears to be due to 479cac6f22a1e6b07c0e3bd5495c704a73ec0261 - I assume the problem referred to in the commit comment is something like

conjoin [ \x -> x+x === x*2
        , \x -> x*x === x^2
        ]

where you want to preserve multiple checks.

I haven't dug into the internal representation of Property - is it possible to have it both ways? Such that conjoin . pure = id?

MaximilianAlgehed commented 5 months ago

The "run once if no quantification" behaviour has been removed in recent versions of QuickCheck in favor of explicit use of once, which appears to work roughly as expected on this example:

$> quickCheck $ True .&&. True
+++ OK, passed 100 tests.
$> quickCheck $ True && True
+++ OK, passed 100 tests.
$> quickCheck $ once $ True && True
+++ OK, passed 1 test.
$> quickCheck $ once $ True .&&. True
+++ OK, passed 1 test.
$> quickCheck $ once True .&&. True
+++ OK, passed 100 tests.
$> quickCheck $ True .&&. once True
+++ OK, passed 100 tests.