由於 pyUnit 附的 unittestgui 怎麼試都沒成功,我改用這個 unittestgui.py:GUI test runner using wxPython。相關說明請見之前的文章。美中不足的是,它不方便載入 test suite,所以我修改了一下這份程式。
程式下載和用法
點此下載修改後的程式碼。使用的範例程式碼如下:
1 2 3 4 5 6 7 8 9 | # all_test_suite.py import unittest import catsinbag.card_factory_test import catsinbag.cash_test def suite(): suites = [] suites.append(unittest.TestLoader().loadTestsFromTestCase(some_module.SomeTestCase)) return unittest.TestSuite(suites) |
執行 unittestgui.py 後,按 Open 選擇 all_test_suite.py 即可載入。
目前這個工具仍有些問題,像是原始碼改過後,得重開檔案載入後才會生效,所以無法一邊改程式碼一邊按 Run Test。還有錯誤訊息顯示得不夠清楚,而且還是顯示在 console 上,不是顯示在 GUI 上。
修改過程心得
參照 unittest官方文件,最方便載入多個 test cases 和 test suites 的方法,是採用下面這段 code:
1 2 3 | suite1 = unittest.TestLoader().loadTestsFromTestCase(SomeTestCase1) suite2 = unittest.TestLoader().loadTestsFromTestCase(SomeTestCase2) alltests = unittest.TestSuite([suite1, suite2]) |
若自己用 console 執行 unittest,只要把 alltests 交給 TextTextRunner 即可,例如:
1 | unittest.TextTestRunner(verbosity=2).run(alltests) |
但是,一個熱愛寫 testing 程式的程式設計師,除了想要有更高品質的程式碼外,內心更渴望看到 Green Bar啊!所以非得用 GUI 版的 unittest 不可。而 unittestgui.py 可以載入 test case、test suite,卻沒辦法載入 module 內產生的 test suite。所以只好直接改 unittestgui.py 的程式碼。關鍵在於 OnMenuOpen() 如何取得 test suite。原本的程式碼如下:
1 2 3 4 5 6 7 | modname, modtype = os.path.splitext(os.path.basename(self.filename)) if modtype.lower() == '.py': moduleToTest = imp.load_source(modname, self.filename, file(self.filename)) elif modtype.lower() in {'.pyc':0, '.pyo':0}: moduleToTest = imp.load_compiled(modname, self.filename, file(self.filename, 'rb')) #print moduleToTest, dir(moduleToTest) self.suite = unittest.defaultTestLoader.loadTestsFromModule(moduleToTest) |
修改後的程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | modname, modtype = os.path.splitext(os.path.basename(self.filename)) if modtype.lower() == '.py': moduleToTest = imp.load_source(modname, self.filename, file(self.filename)) elif modtype.lower() in {'.pyc':0, '.pyo':0}: moduleToTest = imp.load_compiled(modname, self.filename, file(self.filename, 'rb')) #print moduleToTest, dir(moduleToTest) if hasattr(moduleToTest, 'suite'): # use the prepared suite if it exists. if callable(moduleToTest.suite): self.suite = moduleToTest.suite() else: self.suite = moduleToTest.suite else: self.suite = unittest.defaultTestLoader.loadTestsFromModule(moduleToTest) |
利用已讀到的 module: moduleToTest,增加判斷它是否有提供 function suite() 或是 attribute suite,若有的話,直接使用準備好的 test suite,而非從 TestCase 或 TestSuite 中產生。
最後附上執行後的精美圖片,辛苦了這麼久,就是為了看到這 Green Bar 啊!
沒有留言:
張貼留言