1

Beginner at Haskell here.

I have a function, and a bunch of properties to test it with which I've written using quickcheck. The properties work when I run them individually in the interpreter, and the function checks out fine.

However, manually quickchecking with each property in the interpreter by hand (quickCheck prop_this, quickCheck prop_that) is boring, monotonous, and time-consuming. I would like to stick all of this in a program, and have that program run all of the quickchecks. This is where I am stuck.

The basic skeleton of the program is as follows:

imports...

function_which_i_want_to_quickcheck

prop_1
prop_2
etc...

main = do
    quickCheck prop_1
    quickCheck prop_2
    etc...

Everything above main is fine I believe, as it all compiles and works without it. main is what I need help with. I've tried several variations, i.e. not having a do, using a do, assigning results using 'x <- quickCheck y', removing quickCheck from the inside and sticking it on the outside instead, etc. but can't get anything to work.

  1. Can anyone assist with the above?

  2. If I wanted to move everything inside main to another (normal, non-main) function, how would I do it?

EDIT: I appreciate the recommendation for testing frameworks, but what I'm asking for here is trivial to do in any other language, and shouldn't need a testing framework. Why not Haskell?

Also, this works correctly right inside the interpreter. I can't get it to work inside main. Any ideas why?

quickCheck prop_1 >> quickCheck prop_2 >> quickCheck prop_3

Thanks.

user3355020
  • 315
  • 1
  • 9
  • If all of your property is of the same type, then you can put them in a list and do `mapM_`. – Sibi Mar 02 '14 at 12:48
  • 5
    It is not very easy to diagnose a problem with code one cannot see having errors one cannot see. Haskellers have superpowers but there are limits. – n. m. could be an AI Mar 02 '14 at 13:53
  • you have all the information you need to diagnose. read the question. i said all functions and code above main work. as for main, it is a sequence of "quickcheck blah." are you saying you need the real function names or you can't diagnose? – user3355020 Mar 02 '14 at 18:59
  • @user3355020 "can't get anything to work" - the only sensible answer to this is "works for me" (which I herewith give). – Ingo Mar 03 '14 at 12:10
  • 1
    We haven't got the necessary information. You need to give us a complete code sample which fails, so we can run it, see the error message and diagnose the problem. Perhaps there is something subtle about the type of one of your properties that isn't evident here, for instance. – Paul Johnson Mar 03 '14 at 14:15

2 Answers2

3

It is not very clear from the question what problems you have, but generally I'd recommend using a testing framework, such as tasty, to organize your quickcheck tests together:

import Test.Tasty
import Test.Tasty.QuickCheck

main = defaultMain $ testGroup "Tests"
  [ testProperty "+ is commutative" $
      \x y -> x + y == (y + x :: Double)
  , testProperty "+ is associative" $
      \x y z -> (x + y) + z == (x + (y + z) :: Double)
  ]

To run this, you'll need to install the tasty-quickcheck package.

Here's how it looks when executed:

screenshot

Roman Cheplyaka
  • 37,738
  • 7
  • 72
  • 121
1

I've used TestFramework in the past. It allows you to create arbitrarily nested test groups, which gives you a way to change input parameters.

main = do
    defaultMain $ [tier1_tests, ...]

tier1_tests = testGroup "Level One Tests" [tier2_tests1, tier2_tests2, ...]

tier2_tests1 = testGroup "Level Two Testgroup 1" [tier3_tests1, youGetTheIdea, ...]
                 ] 
tier3_tests1 = testGroup "Level Three Testgroup" [
        testProperty "m=32 random encoding with good x" (prop_realTest1 8 32 True),
        testProperty "m=256 random encoding bad x" (prop_realTest2 128 256 False),
        ... ]

prop_realTest1 m goodq b = forAll arbitrary (\ x -> ...)
crockeea
  • 21,651
  • 10
  • 48
  • 101