[Pyunit-interest] Extending unittest with a "Master" Fixture setUp and tearDown
Brought to you by:
purcell
From: W M. <wil...@pw...> - 2007-02-12 23:58:07
|
Greetings Justa-programmers. I am new to this list and python in general. I did a ( really ) quick inspection of the archive for this topic. So if this is old hat, please don't tar and feather me. After about a day of reviewing unittest.py and doing the google shuffle, I managed to extend unittest to run a master_setUp() and master_tearDown() method from my derived TestCase. The reasoning behind this was to avoid unnecessary socket connections/disconnects/reconnections. I needed: Running Master Set-up 1 -- Connection to Server setUp 1 -- Test Local setUp test_1 1 -- Run Test tearDown 1 -- Test Local tearDown .setUp 1 test_2 1 tearDown 1 .setUp 1 test_3 1 tearDown 1 .Running Master tearDown 1 -- Disconnection from Server Where I had three Tests,test_1 test_2 test_3, embedded in my TestCase derived class, each of which could share the socket connection. I could not find any similar code to this. I had considered py.test b/c it touts this functionality as one of its features, http://codespeak.net/py/current/doc/test.html#managing-test-state-across-test-modules-classes-and-methods . I found this implementation cumbersome and confusing, but it did work for what I needed. In my experience, this is a useful feature when configuring a hardware device for an actual test fixture. Alas, I was sure the strong design of unittest would lend to it being extended in this way. So for the google cache, I submit the following example of how I solved this issue. Please, any comments upon how this could be improved or simpler ways to accomplish the same result are welcomed. ( FYI: I use tabs ) I can attach as file, if that is preferred. Sincerely, William Meadows simple_test.py :: #### #!/usr/bin/python import sys import unittest class MyTestSuite( unittest.TestSuite ) : master_setUpName = "master_setUp" master_tearDownName = "master_tearDown" def __init__( self, tests = () ) : unittest.TestSuite.__init__(self,tests) self.numtests = self.countTestCases() self.numtestsleft = self.numtests def run( self, result ) : for test in self._tests : # Sometimes,when thru unittest.main() a MyTestSuite instance gets passed here . # This instance appears to be a Suite of Suites ... # I cannot figure how this get's constructed in unittest ?? if issubclass( type(test), unittest.TestCase ) : if self.numtestsleft == self.countTestCases(): eval("test.%s"%(self.master_setUpName))() self.numtestsleft = self.numtestsleft - 1 if result.shouldStop : break # Run a TestSuite or/ TestCase test(result) if issubclass( type(test), unittest.TestCase ) : if self.numtestsleft == 0 : eval("test.%s"%(self.master_tearDownName))() return result class MyTestLoader( unittest.TestLoader) : suiteClass = MyTestSuite class SimpleTest( unittest.TestCase ) : num = 1 def master_setUp(self): print "Running Master Set-up %d " % ( self.num ) def master_tearDown(self): print "Running Master tearDown %d " % ( self.num ) def setUp(self): print "setUp %d " % ( self.num ) def tearDown(self): print "tearDown %d " % ( self.num ) def test_1(self): print "test_1 %d " % ( self.num ) def test_2(self): print "test_2 %d " % ( self.num ) def test_3(self): print "test_3 %d " % ( self.num ) class SimpleTest3( SimpleTest ) : num = 3 if __name__ == "__main__" : pickOne = None if len(sys.argv) > 1 : pickOne = int(sys.argv[1]) if pickOne == None : unittest.main( testLoader = MyTestLoader() ) #/OR elif pickOne == 1 : unittest.TextTestRunner().run( MyTestLoader().loadTestsFromTestCase(SimpleTest) ) unittest.TextTestRunner().run( MyTestLoader().loadTestsFromTestCase(SimpleTest3) ) #### Sample Output: #### /* notice testoob fails to work correctly with this modification, no idea why. Perhaps, it doesn't pick-up the unittest.main( testLoader = option ) ?? > python /usr/lib/python2.4/site-packages/unittestgui.py test_sample.SimpleTest , does not seem to be working either */ user@ubuntu:~/tmp/test/unittest$ testoob test_sample.py setUp 1 test_1 1 tearDown 1 .setUp 1 test_2 1 tearDown 1 .setUp 1 test_3 1 tearDown 1 .setUp 3 test_1 3 tearDown 3 .setUp 3 test_2 3 tearDown 3 .setUp 3 test_3 3 tearDown 3 . ---------------------------------------------------------------------- Ran 6 tests in 0.002s OK /* This works */ user@ubuntu:~/tmp/test/unittest$ python test_sample.py Running Master Set-up 1 setUp 1 test_1 1 tearDown 1 .setUp 1 test_2 1 tearDown 1 .setUp 1 test_3 1 tearDown 1 .Running Master tearDown 1 Running Master Set-up 3 setUp 3 test_1 3 tearDown 3 .setUp 3 test_2 3 tearDown 3 .setUp 3 test_3 3 tearDown 3 .Running Master tearDown 3 ---------------------------------------------------------------------- Ran 6 tests in 0.001s OK /* this works also */ user@ubuntu:~/tmp/test/unittest$ python test_sample.py 1 Running Master Set-up 1 setUp 1 test_1 1 tearDown 1 .setUp 1 test_2 1 tearDown 1 .setUp 1 test_3 1 tearDown 1 .Running Master tearDown 1 ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK Running Master Set-up 3 setUp 3 test_1 3 tearDown 3 .setUp 3 test_2 3 tearDown 3 .setUp 3 test_3 3 tearDown 3 .Running Master tearDown 3 ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK |