Skip to content

Instantly share code, notes, and snippets.

@bigjason
Created March 5, 2011 23:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bigjason/856821 to your computer and use it in GitHub Desktop.
Save bigjason/856821 to your computer and use it in GitHub Desktop.
Python Scenario Testing Prototype
import unittest
## Scenario Support ##
class ScenarioMeta(type):
def __new__(cls, name, bases, attrs):
new_attrs = {}
for name, val in filter(lambda n: isinstance(n[1], ScenerioTestMeta), attrs.iteritems()):
for id, params in enumerate(val.scenarios if not callable(val.scenarios) else val.scenarios()):
if type(params) in (tuple, list):
params, id = params
# create a unittest discoverable name
test_name = "test_%s_%s" % (val.__name__, id)
# Wrap the scenario in a closure and assign the discoverable
# name.
new_attrs[test_name] = cls._wrap_test(params, val.__test__)
attrs.update(new_attrs)
return super(ScenarioMeta, cls).__new__(cls, name, bases, attrs)
@staticmethod
def _wrap_test(kwargs, meth):
def wrapper(self):
meth(self, **kwargs)
return wrapper
class ScenerioTestMeta(type):
def __new__(cls, name, bases, attrs):
test_meth = attrs.pop("__test__", None)
if test_meth:
# Now that the __test__ method is pulled off the base it can be
# wrapped as static and rebound. This allows it to be re-composed
# to the parent test case.
attrs["__test__"] = staticmethod(test_meth)
return super(ScenerioTestMeta, cls).__new__(cls, name, bases, attrs)
class ScenerioTest(object):
__metaclass__ = ScenerioTestMeta
scenarios = ()
## Unit of code to test ##
def is_numeric(value_in):
try:
float(value_in)
return True
except Exception:
return False
## Test Case ##
class TestIsNumeric(unittest.TestCase):
__metaclass__ = ScenarioMeta
class is_numeric_basic(ScenerioTest):
scenarios = [
dict(val="1", expected=True),
dict(val="-1", expected=True),
dict(val=unicode("123" * 9999), expected=True),
dict(val="Bad String", expected=False),
dict(val="Speaks Volumes", expected=False)
]
scenarios += [(dict(val=unicode(x), expected=True),
"check_unicode_%s" % x) for x in range(-2, 3)]
def __test__(self, val, expected):
actual = is_numeric(val)
if expected:
self.assertTrue(actual)
else:
self.assertFalse(actual)
if __name__ == "__main__":
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment