Computing test methods in unittest.TestCase

Discussion in 'Python' started by Jan Decaluwe, Mar 2, 2004.

  1. Jan Decaluwe

    Jan Decaluwe Guest

    I'm working on a unit test for a finite state machine (FSM). The FSM
    behavior is specified in a dictionary called transitionTable. It has a
    key per state with a tuple of possible transitions as the corresponding
    value. A transition is defined as a number of input values, a next
    state, and a documentation string.

    I want to test each possible transition in a separate test method. For
    a particular transition, a test method could look as follows:

    class FSMTest(unittest.TestCase):
    ....
    def test_START_2(self):
    """Check state START - Switched channels before data started"""
    state, transition = START, transitionTable[START][2]
    sim = Simulation(self.bench(state, transition))
    sim.run()

    As the number of transitions can be large, I want to
    "compute" the test methods, based on the transitionTable info.
    Currently, I have the following:

    class FSMTest(unittest.TestCase):
    ....
    for st, trs in transitionTable.items():
    for i, tr in enumerate(trs):
    def _tmpfunc(self, st=st, tr=tr):
    sim = Simulation(self.bench(st, tr))
    sim.run()
    _tmpfunc.func_doc = "Check state %s - %s" % (st, getDoc(tr))
    exec "test_%s_%s = _tmpfunc" % (st, i)

    This works, but uses some "ugly" tricks:

    * default arguments to pass context info. As the code is executed in
    class context, not function context, I cannot use free variables.
    * The use of 'exec'. unittest looks for methods with name prefix
    'test_' in the class namespace, and I didn't find another way
    to achieve that.

    Anyone with better ideas?

    --
    Jan Decaluwe - Resources bvba - http://jandecaluwe.com
    Losbergenlaan 16, B-3010 Leuven, Belgium
    Python is fun, and now you can design hardware with it:
    http://jandecaluwe.com/Tools/MyHDL/Overview.html
     
    Jan Decaluwe, Mar 2, 2004
    #1
    1. Advertising

  2. Jan Decaluwe

    James Kew Guest

    "Jan Decaluwe" <> wrote in message
    news:...
    >> class FSMTest(unittest.TestCase):

    > ....
    > for st, trs in transitionTable.items():
    > for i, tr in enumerate(trs):
    > def _tmpfunc(self, st=st, tr=tr):
    > sim = Simulation(self.bench(st, tr))
    > sim.run()
    > _tmpfunc.func_doc = "Check state %s - %s" % (st, getDoc(tr))
    > exec "test_%s_%s = _tmpfunc" % (st, i)
    >
    > This works, but uses some "ugly" tricks:
    >
    > * default arguments to pass context info. As the code is executed in
    > class context, not function context, I cannot use free variables.
    > * The use of 'exec'. unittest looks for methods with name prefix
    > 'test_' in the class namespace, and I didn't find another way
    > to achieve that.
    >
    > Anyone with better ideas?


    Define the test methods after defining the class, and inject them into the
    class with setattr:

    class testClass:
    pass

    def makeTest(param):
    def test(self):
    print "test: param=%s" % param
    return test

    setattr(testClass, "test1", makeTest(1))
    setattr(testClass, "testHello", makeTest("Hello"))

    >>> t = testClass()
    >>> t.test1()

    test: param=1
    >>> t.testHello()

    test: param=Hello

    James
     
    James Kew, Mar 2, 2004
    #2
    1. Advertising

  3. Jan Decaluwe

    Peter Otten Guest

    Jan Decaluwe wrote:

    > I'm working on a unit test for a finite state machine (FSM). The FSM
    > behavior is specified in a dictionary called transitionTable. It has a
    > key per state with a tuple of possible transitions as the corresponding
    > value. A transition is defined as a number of input values, a next
    > state, and a documentation string.
    >
    > I want to test each possible transition in a separate test method. For


    [...]

    > As the number of transitions can be large, I want to
    > "compute" the test methods, based on the transitionTable info.


    [...]

    > Anyone with better ideas?


    Use a test suite instead and turn each FSMTest.testXXX() method into a
    TestCase instance:

    class TransitionTest(unittest.TestCase):
    def __init__(self, state, transition):
    unittest.TestCase.__init__(self)
    self.state = state
    self.transition = transition

    def bench(self, state, transition):
    pass

    def runTest(self):
    Simulation(self.bench(self.state, self.transition)).run()

    def __str__(self):
    return "Check state %s - %s" % (self.state, getDoc(self.transition))

    def makeSuite():
    suite = unittest.TestSuite()
    for st, trs in transitionTable.iteritems():
    for tr in trs:
    suite.addTest(TransitionTest(st, tr))
    return suite

    if __name__ == "__main__":
    unittest.main(defaultTest="makeSuite")

    Peter
     
    Peter Otten, Mar 2, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steven Bethard

    unittest.TestCase, lambda and __getitem__

    Steven Bethard, Sep 13, 2004, in forum: Python
    Replies:
    7
    Views:
    458
    Alex Martelli
    Sep 14, 2004
  2. Tom Harris
    Replies:
    1
    Views:
    309
    Diez B. Roggisch
    Nov 27, 2007
  3. Oltmans
    Replies:
    1
    Views:
    844
    Francesco Bochicchio
    Sep 28, 2009
  4. Joel Smith
    Replies:
    1
    Views:
    490
    Peter Otten
    Oct 6, 2009
  5. Scott
    Replies:
    1
    Views:
    136
    Timothy Hunter
    Aug 20, 2005
Loading...

Share This Page