Monday, 18 March 2013

Police your code with fuzz testing

I've just become a convert to Fuzz testing. This is a rather simple idea for testing software that processes some user input: just send in some random junk and see what happens (and keep repeating until something does).

I tried this for some software I've been working on, thinking it was so dumb it couldn't possibly flush out anything useful, but quickly changed my mind. Even more interesting, where the space of all possible user input can be stepped through systematically, fuzz testing can be used to map out the space of allowed input (which may or may not be what you were expecting). For example, you could find all 4-letter words acceptable to OPSIN by using the code below to generate fuzz and use OPSIN through Cinfony (for example) to find out whether an error is raised.

import random

class Fuzzer:
    def __init__(self, allowed, length):
        self.allowed = allowed
        self.length = length

    def systematic(self, text=""):
        if len(text) == self.length:
            yield text
        else:
            for x in self.allowed:
                for y in self.systematic(x+text):
                    yield y

    def random(self):
        return "".join([random.choice(allowed) for x in range(self.length)])

if __name__ == "__main__":
    allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVCWXYZ"
    fuzzer = Fuzzer(allowed, 3)
    for fuzz in fuzzer.systematic():
        print fuzz
    fuzzer = Fuzzer(allowed, 5)
    for i in range(10):
        print fuzzer.random()

No comments: