I have a TestCase class and I have a TestStep class. When a new test step is written, TestStep is subclassed and included in a subclass of TestCase.
One of the things I wanted to avoid doing was having to get the test writer to instantiate the TestSteps. I don't think this is possible in many languages, but Python lets me do it with its ludicrous ability to introspect and add stuff to objects at runtime.
class NewTestCase(TestCase):
class NewTestStep(TestStep):
def body(self):
...test step code goes here...
def body(self):
stepNewTestStep() #call instance of NewTestStep
Note that there's no
stepNewTestStep = NewTestStep()
anywhere, and I can add as many TestSteps as I like to the class. stepNewTestStep
is not hard coded into the TestCase.I'd considered naming the NewTestStep objectsas newTestStep rathe than stepNewTestStep, but I was already getting duplicate names in the tests that I'd written, so decided to add the explicit 'step' prefix.
To a Python newbie like me, this is a bit WTF!?, but stick with me. As ever, real Pythoneers, feel free to tell me of better, more Pythonic ways to do this. Here's how it was done…
import types
class TestCase(object):
def __init__(self):
for name in dir(self):
attribute = self.__getattribute__(name)
if type(attribute) = types.TypeType: # ignore any non classes
for base in attribute.__bases__:
if 'TestStep' in base.__name__: # only interested in TestStep classes
setattr(self, 'step%s' % attribute.__name__, attribute())
In plain English, get the names of all the things in TestCase/NewTestCase. For each, make reference to the object of that name (__getattribute__), see if it derived from TestStep and then create a new instance of it (setattr), called 'step[ClassName]' as part of TestCase/NewTestCase.
Note that NewTestCase inherits the __init__ of TestCase, so dir(self) returns the names of everything in NewTestCase.
No comments:
Post a Comment