An oracle for testing purposes can be a number of things: a person, a specification (like an RFC), a comparable product depending on what you are trying to do. If the oracle happens to be an algorithm then I tend to script it up in order to

  • Have a separate implementation to use as a guide
  • Be able to determine if the application is giving me the correct thing
  • Create test data to use that meets the algorithm

The first 2 are scripting the algorithm up as an oracle instance and the third lets me not have to think about the validity of my test data letting me concentrate on more important parts of the testing effort.

Here is an example that I created to verify or generate an account number. In this scenario the usernames are not sequential, but instead are 9 digits long, cannot start with a 0, can only have numbers and the last digit is a mod-10 check digit. If run with an argument then it will verify the validity of the account number, otherwise it will create a valid one for you.

import random, sys, string

def verify_number(to_verify):
    # length check
    if len(to_verify) != 9:
        # raise an exception with some context
        msg = "Invalid account length"
        raise SystemError, msg # yes, I know, SystemError isn't really the right error

    # only numbers
    for char in to_verify:
        if char not in string.digits:
            print "Accounts can only have numbers"
            sys.exit(1)

    # cant start with zero
    if int(to_verify[0]) == 0:
        print "Accounts cannot start with 0"
        sys.exit(1)

    # checkdigit
    run_total = 0
    for run in to_verify[:-1]:
        run_total += int(run)
    mod = run_total % 10
    if int(to_verify[-1]) != mod:
        print "Check-digit failed"
        sys.exit(1)

    print "Account is valid"    

def generate_number():
    account_num = []
    account_num.append(str(random.randint(1,9)))
    for ix in range(0,7):
        account_num.append(str(random.randint(0,9)))
    run_total = 0
    for run in account_num:
        run_total += int(run)
    mod = run_total % 10
    account_num.append(str(mod))
    print "Your new account number is %s " % "".join(account_num)

if __name__ == "__main__":
    if len(sys.argv) == 2:
        # show a try/except block in a real example
        try:
            # verify provided number
            verify_number(sys.argv[1])
        except SystemError:
            print caught
            sys.exit(1)
    elif len(sys.argv) == 1:
        # generate number
        generate_number()
    else:
        print "usage: my_script.py [account number]"

This happens to be in Python, but I once wrote a number of generators like this in Perl and had them all in a nicely dynamic CGI page which would give you account numbers for any available algorithm. It was pretty slick. I should try to find that code…