Hi Bill,

Agreed, at least in part. I think that a good test suite for a  
language like Clojure should include both fixed values and generated  
ones. I just wanted both APIs to be available at the beginning so that  
volunteers could pick the most appropriate choice for a particular test.

Stuart

> I applaud everyone who has volunteered to help write tests for
> Clojure.  A good test suite not only catches problems but also helps
> beginners learn the language.
>
> Regarding the proposal in the previous post, I think we should be
> careful about drawing inferences between the use of random values and
> the resulting quality of the tests.  In my experience, test developers
> often use random values when fixed, hard-coded values work just as
> well.  I think it is more important to look for (and test) edge
> conditions than it is to pull values out of a bag.  I also think using
> random values makes tests less reproducible.
>
> That's not to say there is never a time for randomization.  I just
> think it can make tests unnecessarily complicated.
>
> Bill
>
> On Oct 26, 12:47 pm, Meikel Brandmeyer <[EMAIL PROTECTED]> wrote:
>> Dear Clojurians,
>>
>> Stuart brought up the idea of implementing a QuickCheck clone
>> for Clojure. I think that this is a good idea, since it provides
>> a much better coverage of possible inputs. I gave it some thought
>> this weekend and the following is, what I came up with. There
>> are some specifics of the API which I will ignore in the beginning.
>> They will be explained later on.
>>
>> Comments, thoughts, improvements appreciated.
>>
>> ClojureCheck generates random input samples and feeds them to
>> the functions under test. The generation is done via generation
>> functions, which are combined via so-called combinators to more
>> complex generators.
>>
>> The core is the function arbitrary. It generates the random values
>> for a given type. As Stuart already suggested, I think a multi
>> method is the best way to model this.
>>
>>    (defmulti arbitrary (fn [x & _] (if (vector? x) (first x) x)))
>>
>> The first value is itself normally unused, since it normally
>> only gives the type on which we dispatch. So we can for example
>> define a generator for integers.
>>
>>    (defmethod arbitrary Integer
>>      [_ size]
>>      (int (Math/round (* size (.nextDouble *prng*)))))
>>
>>    (arbitrary Integer 100)
>>
>> To use a generator one uses for-all.
>>
>>    (for-all [x Integer
>>              y Integer]
>>      (test-is/is (= (+ x y) (+ y x))))
>>
>> This code actually cannot be used directly. You may have noticed
>> the unexplained size parameter in the arbitrary call. This is a
>> special parameters passed to the generators to allow a scaling
>> of the test samples. So a generator of lists may start with short
>> lists and may generate longer and longer lists as the test iterates.
>> To hide this from the developer for-all actually returns a generator
>> itself, ie. a function which accepts the size parameter and passes
>> it on the generators in the binding form. So to run actually the
>> tests, one uses the property function.
>>
>>    (property
>>      (for-all [x Integer
>>                y Integer]
>>        (test-is/is (= (+ x y) (+ y x)))))
>>
>> This runs the tests for certain (configurable) number of iterations.
>> Binding x and y to random integers each time.
>>
>> But sometimes one wants to pass parameters to the generators. I
>> thought about the way eg. require does this: (require [foo :as bar]).
>> So I thought one could do this by specifying a vector in the binding
>> form.
>>
>>    (for-all [x [:IntegerRange 100 1000]]
>>      (test-something-with x))
>>
>>    (defmethod arbitrary :IntegerRange
>>      [[_ mn mx] _]
>>      (int (Math/round (+ mn (* (- mx mn) (.nextDouble *prng*))))))
>>
>> The environment like the random number generator, the number of
>> test iterations etc. would be configurable at runtime.
>>
>> A first prototype looks promising. But before I run to far in the
>> wrong direction, I'd like to ask for comments on the API so far.
>> Especially things like passing arguments via a vector...
>>
>> Sincerely
>> Meikel
>>
>>  smime.p7s
>> 5KViewDownload
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to