hacking automatic reductions into random testing tool

This commit is contained in:
Mike Dirolf 2009-01-21 16:33:31 -05:00
parent 7edf75ecdb
commit 801f23854e
2 changed files with 46 additions and 1 deletions

View File

@ -3,12 +3,14 @@ import sys
import traceback
import datetime
import re
import types
from objectid import ObjectId
from dbref import DBRef
from son import SON
gen_target = 100
reduction_attempts = 100
examples = 5
def lift(value):
@ -120,6 +122,47 @@ def gen_mongo_list(depth):
def gen_mongo_dict(depth):
return map(gen_dict(gen_unicode(gen_range(0, 20)), gen_mongo_value(depth - 1), gen_range(0, 10)), SON)
# TODO this is a hack - only really works for mongo_dicts right now...
def simplify(case):
if isinstance(case, SON):
simplified = SON(case) # make a copy!
if random.choice([True, False]):
# delete
if not len(simplified.keys()):
return (False, case)
del simplified[random.choice(simplified.keys())]
return (True, simplified)
else:
# simplify a value
if not len(simplified.items()):
return (False, case)
(key, value) = random.choice(simplified.items())
(success, value) = simplify(value)
simplified[key] = value
return (success, success and simplified or case)
if isinstance(case, types.ListType):
simplified = list(case)
if random.choice([True, False]):
# delete
if not len(simplified):
return (False, case)
simplified.pop(random.randrange(len(simplified)))
return (True, simplified)
else:
# simplify an item
if not len(simplified):
return (False, case)
index = random.randrange(len(simplified))
(success, value) = simplify(simplified[index])
simplified[index] = value
return (success, success and simplified or case)
return (False, case)
def reduce(case, predicate, reductions=0):
for _ in range(reduction_attempts):
(reduced, simplified) = simplify(case)
if reduced and not predicate(simplified):
return reduce(simplified, predicate, reductions + 1)
return (reductions, case)
def isnt(predicate):
return lambda x: not predicate(x)
@ -131,7 +174,8 @@ def check(predicate, generator):
case = generator()
try:
if not predicate(case):
counter_examples.append(repr(case))
reduction = reduce(case, predicate)
counter_examples.append("after %s reductions: %r" % reduction)
except:
counter_examples.append("%r : %s" % (case, traceback.format_exc()))
return counter_examples

View File

@ -92,6 +92,7 @@ class TestBSON(unittest.TestCase):
helper({"false": False})
helper({"an array": [1, True, 3.8, u"world"]})
helper({"an object": {"test": u"something"}})
helper(SON([(u'a date', datetime.datetime(1993, 4, 4, 2, 58, 4, 231000))]))
def from_then_to_dict(dict):
return dict == (BSON.from_dict(dict)).to_dict()