[Python unittest] 3-Organizing test code
?
-
組織測(cè)試代碼
前面已經(jīng)了解到測(cè)試的原理和步驟,但只是默認(rèn)類string的測(cè)試,如果是我們自己寫的類改怎么測(cè)試呢?
如下
class Widget(object):def __init__(self,name,width=50,height=50):self.name = nameself.width = widthself.height = heightdef __repr__(self):return "Widget({0})".format(self.name)# 返回大小def size(self):return (self.width, self.height)#重設(shè)大小def resize(self, *args):try:self.width = args[0]self.height = args[1]except:passreturn self.size()#其他方法def dispose(self):print '這里是tearDown'pass?測(cè)試用例可以這樣寫
import unittestclass DefaultWidgetSizeTestCase(unittest.TestCase):def runTest(self):widget = Widget('The widget')self.assertEqual(widget.size(), (50, 50), 'incorrect default size')?結(jié)果
python -m unittest users.tests.DefaultWidgetSizeTestCase . ---------------------------------------------------------------------- Ran 1 test in 0.000sOK?實(shí)際情況中,如果對(duì)該類我們有一百個(gè)測(cè)試用例需要寫,難道要寫100次widget = Widget('The widget')嗎?我們?cè)愁惖姆?wù)宗旨是什么?從不寫重復(fù)的代碼
import unittestclass SimpleWidgetTestCase(unittest.TestCase):def setUp(self):self.widget = Widget('The widget')
所以u(píng)nittest給我們提供了setup,setup是每一個(gè)測(cè)試用例runTest之前都會(huì)執(zhí)行的函數(shù),相當(dāng)于給我們提供了一個(gè)準(zhǔn)備環(huán)境的方法
class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):def runTest(self):self.assertEqual(self.widget.size(), (50,50),'incorrect default size')class WidgetResizeTestCase(SimpleWidgetTestCase):def runTest(self):self.widget.resize(100,150)self.assertEqual(self.widget.size(), (100,150),'wrong size after resize')?
python -m unittest users.tests .. ---------------------------------------------------------------------- Ran 2 tests in 0.000sOK?兩個(gè)有 runTest 的測(cè)試用例都自動(dòng)執(zhí)行了父類的setup函數(shù),當(dāng)setup出錯(cuò)后,測(cè)試用例就不會(huì)執(zhí)行了
相似的,unittest提供了在測(cè)試用例執(zhí)行之后可以自動(dòng)執(zhí)行的方法tearDown,可以讓我們做一些自己需要的事
class SimpleWidgetTestCase(unittest.TestCase):def setUp(self):self.widget = Widget('The widget')def tearDown(self):self.widget.dispose()self.widget = None?
python -m unittest users.tests 這里是tearDown .這里是tearDown . ---------------------------------------------------------------------- Ran 2 tests in 0.000sOK?只要setup成功,不論測(cè)試用例是否正確,tearDown都會(huì)執(zhí)行
class WidgetTestCase(unittest.TestCase):def setUp(self):self.widget = Widget('The widget')def tearDown(self):self.widget.dispose()self.widget = Nonedef test_default_size(self):self.assertEqual(self.widget.size(), (50,50),'incorrect default size')def test_resize(self):self.widget.resize(100,150)self.assertEqual(self.widget.size(), (100,150),'wrong size after resize')
現(xiàn)在每一個(gè)測(cè)試用例都要繼承相同的測(cè)試夾具,這讓人感覺很不舒服,unittest提供了如下辦法,很像java的JUnit?
python -m unittest users.tests.WidgetTestCase 這里是tearDown .這里是tearDown . ---------------------------------------------------------------------- Ran 2 tests in 0.000sOK?這里沒有runTest函數(shù),而是用test_開頭的方法代替,每一個(gè)test_開頭的方法都會(huì)被當(dāng)作一個(gè)測(cè)試獨(dú)立運(yùn)行,包括setup和tearDown也是獨(dú)立的
if __name__ == '__main__':widgetTestSuite = unittest.TestSuite()widgetTestSuite.addTest(WidgetTestCase('test_default_size'))widgetTestSuite.addTest(WidgetTestCase('test_resize'))#suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)unittest.TextTestRunner(verbosity=2).run(widgetTestSuite)
如果只想運(yùn)行部分測(cè)試用例改怎么辦呢??將你想運(yùn)行的測(cè)試用例加入TestSuite
python */users/tests.py test_default_size (__main__.WidgetTestCase) ... 這里是tearDown ok test_resize (__main__.WidgetTestCase) ... 這里是tearDown ok---------------------------------------------------------------------- Ran 2 tests in 0.001sOK?或者將你想測(cè)試的類加載為suite,可以測(cè)試整個(gè)類的所有用例
if __name__ == '__main__':#widgetTestSuite = unittest.TestSuite()#widgetTestSuite.addTest(WidgetTestCase('test_default_size'))#widgetTestSuite.addTest(WidgetTestCase('test_resize'))suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)unittest.TextTestRunner(verbosity=2).run(suite)?
python */users/tests.py test_default_size (__main__.WidgetTestCase) ... 這里是tearDown ok test_resize (__main__.WidgetTestCase) ... 這里是tearDown ok---------------------------------------------------------------------- Ran 2 tests in 0.001sOK?更美觀的做法是
if __name__ == '__main__':def suite():suite = unittest.TestSuite()suite.addTest(WidgetTestCase('test_default_size'))suite.addTest(WidgetTestCase('test_resize'))return suitedef suite_map():tests = ['test_default_size', 'test_resize']return unittest.TestSuite(map(WidgetTestCase, tests))unittest.TextTestRunner(verbosity=2).run(suite())?
python */users/tests.py test_default_size (__main__.WidgetTestCase) ... 這里是tearDown ok test_resize (__main__.WidgetTestCase) ... 這里是tearDown ok---------------------------------------------------------------------- Ran 2 tests in 0.000sOK?有時(shí)候需要阻止各個(gè)測(cè)試用例,很簡(jiǎn)單測(cè)試套件TestSuite像TestCase一樣被加入TestSuite
if __name__ == '__main__':def suite():suite = unittest.TestSuite()suite.addTest(WidgetTestCase('test_default_size'))suite.addTest(WidgetTestCase('test_resize'))return suitedef suite_map():tests = ['test_default_size', 'test_resize']return unittest.TestSuite(map(WidgetTestCase, tests))alltest = unittest.TestSuite([suite(), suite_map()])unittest.TextTestRunner(verbosity=2).run(alltest)?
python */users/tests.py test_default_size (__main__.WidgetTestCase) ... 這里是tearDown ok test_resize (__main__.WidgetTestCase) ... 這里是tearDown ok test_default_size (__main__.WidgetTestCase) ... 這里是tearDown ok test_resize (__main__.WidgetTestCase) ... 這里是tearDown ok---------------------------------------------------------------------- Ran 4 tests in 0.001sOK?
測(cè)試代碼可以放在任何地方,不過有幾個(gè)原則需要注意:
- 測(cè)試模塊可以獨(dú)立在命令行執(zhí)行
- 測(cè)試代碼可以很容易的從項(xiàng)目中分離出來
- ?????? 沒有合理的理由不要改變測(cè)試代碼來適應(yīng)它所測(cè)試的代碼
- ?????? 代碼的修改應(yīng)該比測(cè)試代碼的修改頻繁的多
- ?????? 被測(cè)試代碼重構(gòu)更容易
- ?????? 用C編寫的模塊的測(cè)試無論如何必須是獨(dú)立的模塊,那么為什么不一致呢?
- ?????? 測(cè)試策略發(fā)生變化,不需要更改源代碼
轉(zhuǎn)載于:https://www.cnblogs.com/lazySmeagol/p/7452460.html
總結(jié)
以上是生活随笔為你收集整理的[Python unittest] 3-Organizing test code的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么将string list 转成有特殊
- 下一篇: 学习教程及工具