1. 程式人生 > 實用技巧 >Python-unittest框架使用筆錄

Python-unittest框架使用筆錄

unittest框架

  unittest是python自動測試框架,核心:test case, test suite, test runner, test fixture。

  官方文件,python3版本:https://docs.python.org/zh-tw/3/library/unittest.html

1.test fixture

  對於一個測試用例環境的搭建和銷燬,是一個fixture。啟用testfixture(測試執行前:需要準備測試環境,eg:連線資料庫、開啟瀏覽器等;測試執行後:還原資料庫、關閉瀏覽器。)

  • setUp():準備環境,執行每個測試用例的前置條件;
  • tearDown():環境還原,執行每個測試用例的後置條件;
  • setUpClass():必須使用哪@classmethod裝飾器,所有case執行的前置條件,值執行一次;
  • tearDownClass():必須使用@classmethod裝飾器,所有case執行完成後只執行一次。 

2.TestCase

  一個class繼承了unittest.TestCase,即是一個測試用例,測試方法以test開頭;

  測試環境準備setUp()|setUpClass()、執行程式碼run()、測試環境後還原tearDown()|tearDownClass()。

import unittest

def add(a,b):
return a+b

def divide(a,b):

return a/b

class testfunc(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("開始")

@classmethod
def tearDownClass(cls):
print("結束")

def test_add(self):
print("執行加法")
self.assertEqual(3,add(1,2))

def test_divide(self):
print("執行除法")

if __name__ == '__main__':

unittest.main()

前後各執行一次;如果用setUp()和tearDown(),會在每個test_func()前後各執行一次。

備註:unittest.main(verbosity=2),會輸出詳細的測試結果,verbosity預設值為1,若設定為0,則不輸出用例的執行結果。

Console: test_add (__main__.testfunc) ... ok
      test_divide (__main__.testfunc) ... ok

3.TestSuite

 控制test測試用例的執行順序,testsuit還可以包含testsuit。 

if __name__ == '__main__':

    test = [testfunc("test_divide"), testfunc("test_add")]
suite = unittest.TestSuite()
suite.addTests(test)

runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

Console:  test_divide (__main__.testfunc) ... ok
       test_add (__main__.testfunc) ... ok

4.整體流程

  • TestCase->TestLoader載入TestCase到TestSuite->TextTestRunner執行TestSuite,並將執行結果儲存在TextTestResult中;
  • 通過命令或者unittest.main()執行時,main會呼叫TextTestRunner中的run來執行;
  • 或者可以通過TextTestRunner來執行用例;
  • Runner執行時,預設將執行結果輸出到控制檯,可以使用HTMLTestRunner將結果輸出到Html中。

5.Skip裝飾器

  skip裝飾器主要有3種:

  • unittest.skip(reason):無條件跳過執行,reason描述為什麼跳過測試;
  • unittest.skiplf(condition,reason):如果condition為True,跳過執行;
  • unittest.skipUnless(condition,reason):如果condition不為True,跳過執行;
  • expected failure:使用@unittest.expectedFailure裝飾器,如果test失敗了,這個test不計入失敗的case數目。

  eg:

    @unittest.skip("不想執行")
    def test_add(self):
    print("執行加法")
    self.assertEqual(3, add(1, 2))
console:  test_add (__main__.testfunc) ... skipped '不想執行'

6.生成html格式的測試報告

  unittest預設生成的測試報告是txt格式,使用的是TextTestRunner(),如果想要生成html報告,可以使用HtmlTestRunner代替TextTestRunner。

  1.下載檔案

  2.修改檔案

  • 第94行,將import StringIO修改成import io
  • 第539行,將self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
  • 第642行,將if not rmap.has_key(cls):修改成if not cls in rmap:
  • 第766行,將uo = o.decode('latin-1')修改成uo = e
  • 第772行,將ue = e.decode('latin-1')修改成ue = e
  • 第631行,將print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))

  3.在工程目錄中建立result.html

  from  HTMLTestRunner import HTMLTestRunner
  if __name__ == '__main__':
  f=open('./result.html','wb')
  runner = HTMLTestRunner(stream=f,
title='MathFunc Test Report',
description='用例執行情況',verbosity=2
)
  runner.run(suite)