1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package quick implements utility functions to help with black box testing.
7 // The testing/quick package is frozen and is not accepting new features.
20 var defaultMaxCount
*int = flag
.Int("quickchecks", 100, "The default number of iterations for each check")
22 // A Generator can generate random values of its own type.
23 type Generator
interface {
24 // Generate returns a random instance of the type on which it is a
25 // method using the size as a size hint.
26 Generate(rand
*rand
.Rand
, size
int) reflect
.Value
29 // randFloat32 generates a random float taking the full range of a float32.
30 func randFloat32(rand
*rand
.Rand
) float32 {
31 f
:= rand
.Float64() * math
.MaxFloat32
32 if rand
.Int()&1 == 1 {
38 // randFloat64 generates a random float taking the full range of a float64.
39 func randFloat64(rand
*rand
.Rand
) float64 {
40 f
:= rand
.Float64() * math
.MaxFloat64
41 if rand
.Int()&1 == 1 {
47 // randInt64 returns a random int64.
48 func randInt64(rand
*rand
.Rand
) int64 {
49 return int64(rand
.Uint64())
52 // complexSize is the maximum length of arbitrary values that contain other
54 const complexSize
= 50
56 // Value returns an arbitrary value of the given type.
57 // If the type implements the Generator interface, that will be used.
58 // Note: To create arbitrary values for structs, all the fields must be exported.
59 func Value(t reflect
.Type
, rand
*rand
.Rand
) (value reflect
.Value
, ok
bool) {
60 return sizedValue(t
, rand
, complexSize
)
63 // sizedValue returns an arbitrary value of the given type. The size
64 // hint is used for shrinking as a function of indirection level so
65 // that recursive data structures will terminate.
66 func sizedValue(t reflect
.Type
, rand
*rand
.Rand
, size
int) (value reflect
.Value
, ok
bool) {
67 if m
, ok
:= reflect
.Zero(t
).Interface().(Generator
); ok
{
68 return m
.Generate(rand
, size
), true
71 v
:= reflect
.New(t
).Elem()
72 switch concrete
:= t
; concrete
.Kind() {
74 v
.SetBool(rand
.Int()&1 == 0)
76 v
.SetFloat(float64(randFloat32(rand
)))
78 v
.SetFloat(randFloat64(rand
))
79 case reflect
.Complex64
:
80 v
.SetComplex(complex(float64(randFloat32(rand
)), float64(randFloat32(rand
))))
81 case reflect
.Complex128
:
82 v
.SetComplex(complex(randFloat64(rand
), randFloat64(rand
)))
84 v
.SetInt(randInt64(rand
))
86 v
.SetInt(randInt64(rand
))
88 v
.SetInt(randInt64(rand
))
90 v
.SetInt(randInt64(rand
))
92 v
.SetInt(randInt64(rand
))
94 v
.SetUint(uint64(randInt64(rand
)))
96 v
.SetUint(uint64(randInt64(rand
)))
98 v
.SetUint(uint64(randInt64(rand
)))
100 v
.SetUint(uint64(randInt64(rand
)))
102 v
.SetUint(uint64(randInt64(rand
)))
103 case reflect
.Uintptr
:
104 v
.SetUint(uint64(randInt64(rand
)))
106 numElems
:= rand
.Intn(size
)
107 v
.Set(reflect
.MakeMap(concrete
))
108 for i
:= 0; i
< numElems
; i
++ {
109 key
, ok1
:= sizedValue(concrete
.Key(), rand
, size
)
110 value
, ok2
:= sizedValue(concrete
.Elem(), rand
, size
)
112 return reflect
.Value
{}, false
114 v
.SetMapIndex(key
, value
)
117 if rand
.Intn(size
) == 0 {
118 v
.Set(reflect
.Zero(concrete
)) // Generate nil pointer.
120 elem
, ok
:= sizedValue(concrete
.Elem(), rand
, size
)
122 return reflect
.Value
{}, false
124 v
.Set(reflect
.New(concrete
.Elem()))
128 numElems
:= rand
.Intn(size
)
129 sizeLeft
:= size
- numElems
130 v
.Set(reflect
.MakeSlice(concrete
, numElems
, numElems
))
131 for i
:= 0; i
< numElems
; i
++ {
132 elem
, ok
:= sizedValue(concrete
.Elem(), rand
, sizeLeft
)
134 return reflect
.Value
{}, false
139 for i
:= 0; i
< v
.Len(); i
++ {
140 elem
, ok
:= sizedValue(concrete
.Elem(), rand
, size
)
142 return reflect
.Value
{}, false
147 numChars
:= rand
.Intn(complexSize
)
148 codePoints
:= make([]rune
, numChars
)
149 for i
:= 0; i
< numChars
; i
++ {
150 codePoints
[i
] = rune(rand
.Intn(0x10ffff))
152 v
.SetString(string(codePoints
))
155 // Divide sizeLeft evenly among the struct fields.
162 for i
:= 0; i
< n
; i
++ {
163 elem
, ok
:= sizedValue(concrete
.Field(i
).Type
, rand
, sizeLeft
)
165 return reflect
.Value
{}, false
170 return reflect
.Value
{}, false
176 // A Config structure contains options for running a test.
178 // MaxCount sets the maximum number of iterations.
179 // If zero, MaxCountScale is used.
181 // MaxCountScale is a non-negative scale factor applied to the
183 // If zero, the default is unchanged.
184 MaxCountScale
float64
185 // Rand specifies a source of random numbers.
186 // If nil, a default pseudo-random source will be used.
188 // Values specifies a function to generate a slice of
189 // arbitrary reflect.Values that are congruent with the
190 // arguments to the function being tested.
191 // If nil, the top-level Value function is used to generate them.
192 Values
func([]reflect
.Value
, *rand
.Rand
)
195 var defaultConfig Config
197 // getRand returns the *rand.Rand to use for a given Config.
198 func (c
*Config
) getRand() *rand
.Rand
{
200 return rand
.New(rand
.NewSource(time
.Now().UnixNano()))
205 // getMaxCount returns the maximum number of iterations to run for a given
207 func (c
*Config
) getMaxCount() (maxCount
int) {
208 maxCount
= c
.MaxCount
210 if c
.MaxCountScale
!= 0 {
211 maxCount
= int(c
.MaxCountScale
* float64(*defaultMaxCount
))
213 maxCount
= *defaultMaxCount
220 // A SetupError is the result of an error in the way that check is being
221 // used, independent of the functions being tested.
222 type SetupError
string
224 func (s SetupError
) Error() string { return string(s
) }
226 // A CheckError is the result of Check finding an error.
227 type CheckError
struct {
232 func (s
*CheckError
) Error() string {
233 return fmt
.Sprintf("#%d: failed on input %s", s
.Count
, toString(s
.In
))
236 // A CheckEqualError is the result CheckEqual finding an error.
237 type CheckEqualError
struct {
243 func (s
*CheckEqualError
) Error() string {
244 return fmt
.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s
.Count
, toString(s
.In
), toString(s
.Out1
), toString(s
.Out2
))
247 // Check looks for an input to f, any function that returns bool,
248 // such that f returns false. It calls f repeatedly, with arbitrary
249 // values for each argument. If f returns false on a given input,
250 // Check returns that input as a *CheckError.
253 // func TestOddMultipleOfThree(t *testing.T) {
254 // f := func(x int) bool {
255 // y := OddMultipleOfThree(x)
256 // return y%2 == 1 && y%3 == 0
258 // if err := quick.Check(f, nil); err != nil {
262 func Check(f
interface{}, config
*Config
) error
{
264 config
= &defaultConfig
267 fVal
, fType
, ok
:= functionAndType(f
)
269 return SetupError("argument is not a function")
272 if fType
.NumOut() != 1 {
273 return SetupError("function does not return one value")
275 if fType
.Out(0).Kind() != reflect
.Bool
{
276 return SetupError("function does not return a bool")
279 arguments
:= make([]reflect
.Value
, fType
.NumIn())
280 rand
:= config
.getRand()
281 maxCount
:= config
.getMaxCount()
283 for i
:= 0; i
< maxCount
; i
++ {
284 err
:= arbitraryValues(arguments
, fType
, config
, rand
)
289 if !fVal
.Call(arguments
)[0].Bool() {
290 return &CheckError
{i
+ 1, toInterfaces(arguments
)}
297 // CheckEqual looks for an input on which f and g return different results.
298 // It calls f and g repeatedly with arbitrary values for each argument.
299 // If f and g return different answers, CheckEqual returns a *CheckEqualError
300 // describing the input and the outputs.
301 func CheckEqual(f
, g
interface{}, config
*Config
) error
{
303 config
= &defaultConfig
306 x
, xType
, ok
:= functionAndType(f
)
308 return SetupError("f is not a function")
310 y
, yType
, ok
:= functionAndType(g
)
312 return SetupError("g is not a function")
316 return SetupError("functions have different types")
319 arguments
:= make([]reflect
.Value
, xType
.NumIn())
320 rand
:= config
.getRand()
321 maxCount
:= config
.getMaxCount()
323 for i
:= 0; i
< maxCount
; i
++ {
324 err
:= arbitraryValues(arguments
, xType
, config
, rand
)
329 xOut
:= toInterfaces(x
.Call(arguments
))
330 yOut
:= toInterfaces(y
.Call(arguments
))
332 if !reflect
.DeepEqual(xOut
, yOut
) {
333 return &CheckEqualError
{CheckError
{i
+ 1, toInterfaces(arguments
)}, xOut
, yOut
}
340 // arbitraryValues writes Values to args such that args contains Values
341 // suitable for calling f.
342 func arbitraryValues(args
[]reflect
.Value
, f reflect
.Type
, config
*Config
, rand
*rand
.Rand
) (err error
) {
343 if config
.Values
!= nil {
344 config
.Values(args
, rand
)
348 for j
:= 0; j
< len(args
); j
++ {
350 args
[j
], ok
= Value(f
.In(j
), rand
)
352 err
= SetupError(fmt
.Sprintf("cannot create arbitrary value of type %s for argument %d", f
.In(j
), j
))
360 func functionAndType(f
interface{}) (v reflect
.Value
, t reflect
.Type
, ok
bool) {
361 v
= reflect
.ValueOf(f
)
362 ok
= v
.Kind() == reflect
.Func
370 func toInterfaces(values
[]reflect
.Value
) []interface{} {
371 ret
:= make([]interface{}, len(values
))
372 for i
, v
:= range values
{
373 ret
[i
] = v
.Interface()
378 func toString(interfaces
[]interface{}) string {
379 s
:= make([]string, len(interfaces
))
380 for i
, v
:= range interfaces
{
381 s
[i
] = fmt
.Sprintf("%#v", v
)
383 return strings
.Join(s
, ", ")