Generating custom random inputs for your property based test in golang

Golang’s quick testing package is great for generating random input for your property based test. Sometimes you want to control how the input values are generated. Here’s how you can create a custom generator for the input parameters to your property based test.

Lets assume you want to test the function IsValid(string) with many random inputs …. but …. the input may only contain characters in range a-z, A-Z, and 0-9. Here’s how to do it:

func randomAlphaNumericString(output []reflect.Value, rnd *rand.Rand) {
    alphabet := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
    size := rnd.Intn(8192)
    v := reflect.New(reflect.TypeOf("")).Elem()
    v.SetString(randStringOfLen(rnd, size, alphabet))
    output[0] = v
}

//Generates a string of len n containing random characters from alphabet
func randStringOfLen(rnd *rand.Rand, n int, alphabet[]rune) string {
    b := make([]rune, n)
    for i := range b {
        b[i] = alphabet[rnd.Intn(len(alphabet))]
    }
    return string(b)
}

func TestMyMethod(t *testing.T) {
    propertyTest := func(input string) bool { return true == IsValue(input) }
    c := quick.Config{MaxCount: 1000, Values: randomAlphaNumericString}
    if err := quick.Check(propertyTest , &c); err != nil {
        t.Error(err)
    }
}

Lets break it down into steps:

Firstly we define our propertyTest to check all input strings are valid. So far nothing special. This function takes a single string input parameter.

The quick.Config struct has the Values member. This member lets you supply a function to generate whatever parameters propertyTest needs. In our case the randomAlphaNumericString function does that job.

The randomAlphaNumericString function generates a suitable random string and it stores it as a reflect.Value in the output array at the position where the propertyTest expects to receive a string parameter.