24 5月 2013

[Python] 為Python2.5 unittest 加上setUpClass & tearDownClass 的功能

最近使用 Sikuli 替Project作AutoTest的功能,以Python的unittest為架構下去撰寫,發現有些綁手綁腳的地方,因為Sikuli是使用Jython 2.5,連帶的unittest也止於Python 2.5的版本。由於測試的項目眾多,需要撰寫多個TestCase,所以setUpClasstearDownClass更顯得重要,可以為每個TestCase做pre-process與post-process。偏偏setUpClass與tearDownClass是在Python 2.7後才支援的,所以想在Sikuli裡套用的話,必須自己加一些Code才行了。



說明一下,TestCase裡的setUp與tearDown是TestCase裡的每一個 test function 的pre-processing & post-processing,而setUpClass與tearDownClass是整個TestCase被run起來的pre-processing & post-processing。

以下的sample code,主要就是繼承TestSuite,定義一個自己的MyTestSuite,override run(),讓它試著去執行setUpClass與tearDownClass。

import unittest
import traceback
class MyTestSuite(unittest.TestSuite):
    # sikuli jython 2.5 unittest doesn't have setUpClass & tearDownClass
    # Add the class to support this feature
    def __init__(self,*argv,**argd):
        unittest.TestSuite.__init__(self, *argv, **argd)
    
    def run(self, result):
        sample = self._tests[0] if len(self._tests)>0 else None
        if sample and hasattr(sample, 'setUpClass'):
            try:
                sample.setUpClass()
            except:
                traceback.print_exc()
        
        for test in self._tests:
            if result.shouldStop:
                break
            test(result)
            
        if sample and hasattr(sample, 'tearDownClass'):
            try:
                sample.tearDownClass()
            except:
                traceback.print_exc()
        return result

class MyTestCase(unittest.TestCase):
    def setUpClass(self):
        print 'MyTestCase::setUpClass'
    def tearDownClass(self):
        print 'MyTestCase::tearDownClass'
    def test_MyTest1(self):
        print 'MyTestCase::MyTest1'
    def test_MyTest2(self):
        print 'MyTestCase::MyTest2'

if __name__ == '__main__':
    suites = unittest.TestSuite([unittest.makeSuite(MyTestCase, suiteClass=MyTestSuite)])
    runner = unittest.TextTestRunner()
    runner.run(suites)
    # output result sequence ...
    #>>> MyTestCase::setUpClass
    #>>> MyTestCase::MyTest1
    #>>> MyTestCase::MyTest2
    #>>> MyTestCase::tearDownClass

沒有留言: