Tarek Soliman
Tarek Soliman

Reputation: 71

What does the maxSize field describe in Args from Test.QuickCheck?

I'm looking at maxSize in Args. its description says: "Size to use for the biggest test cases". But how is the size of test cases determined? I'd rather to ask than to go through the source code:

myArgs :: Args
myArgs = Args{replay=Nothing
             ,maxSuccess=1000
             ,maxDiscardRatio=1
             ,maxSize=1
             ,chatty=False
             ,maxShrinks=0}

So for example if I have an arbitrary of type Gen String and another of type Gen [String], then if maxSize=1 this means that the length of the generated string is 1 and the length of the generated list of String is 1?

Upvotes: 2

Views: 252

Answers (3)

Ari Fordsham
Ari Fordsham

Reputation: 2515

The meaning of the size parameter is somewhat arbitrary. The manual says:

Different test data generators interpret the size parameter in different ways: some ignore it, while the list generator, for example, interprets it as an upper bound on the length of generated lists. You are free to use it as you wish to control your own test data generators.

It's basically an integer that the framework passes to the arbitrary action, which begins at 0 and grows gradually. This allows test cases to start simpler and get gradually more complex. As examples, this is length for lists and strings, or absolute magnitude for integers. Several combinators are provided for manipulsting the size parameter.

The maxSize configuration option is provided to allow you to trade-off numbers of tests with individual test complexity. If you specify a large number of tests, do you want the complexity of the data to keep increasing (possibly causing large slowdowns) or do you just want to test lots of cases once a certain complexity threshold is reached?

Upvotes: 1

radrow
radrow

Reputation: 7169

According to the outdated manual it means length for lists (note that String is also a list). The documentation does not seem to specify it anywhere for the particular instances.

The size factor in the sized function mentioned in the manual is calculated with the following comment:

-- e.g. with maxSuccess = 250, maxSize = 100, goes like this: -- 0, 1, 2, ..., 99, 0, 1, 2, ..., 99, 0, 2, 4, ..., 98.

Also, looking at the code it limits integral values by bounding them from -size to size.

Upvotes: 1

Mark Seemann
Mark Seemann

Reputation: 233347

If I recall correctly, each Arbitrary instance is free to respect or use the size parameter as it makes sense. For instance, size doesn't make much sense for an Arbitrary for Bool.

Try experimenting with it yourself. For lists, it definitely has an effect like you assume:

Prelude Test.QuickCheck> propList = const True :: [Int] -> Bool

Prelude Test.QuickCheck> verboseCheckWith (Test.QuickCheck.stdArgs { maxSize = 2 }) propList
Passed:
[]

Passed:
[1]

Passed:
[]

Passed:
[0]

Passed:
[]

Passed:
[1]

(I've edited the output to get the point across, because the actual output is, as implied by the function name, verbose.)

Upvotes: 1

Related Questions