Unittest單元測試框架


  • 什么是單元測試?

單元測試是對最小的軟件設計單元(模塊、類)進行驗證,它使用開發文檔中對模塊的描述作為指南,對重要的程序分支進行測試以發現模塊中的錯誤。

  •  單元測試框架可以解決說明問題?

1、提供用例組織與執行

2、提供豐富的斷言方法

3、提供豐富的日志

 

  • 重要概念

1.Test Case 測試用例

繼承unittest.TestCase的子類里的每個名為test*的函數都被視為單個測試用例,前后執行setUp()和tearDown()

 

 

2.Test Suite 測試用例集合——把多個測試用例集合在一起執行,可以通過addTest加載TestCase到TestSuite中。

  -單元測試的加載方式有2種:一種是通過unittest.main()來啟動單元測試的測試模塊(文件);1.被測試類繼承了unittest.TestCase;2.被測試的函數名為test*

  -一種是添加到testsuite集合中再加載所有的被測試對象,而testsuit里存放的就是單元測試的用例。

  (另一種TestLoader類的dicover方法直接加載文件中所有被測試對象,其實也應用了testsuite原理)

 

 1 # -*-coding:utf-8-*-
 2 
 3 import unittest
 4 
 5 def setUpModule():  # 模塊的前后執行
 6     print("測試模塊開始-------")
 7 def tearDownModule():
 8     print("測試模塊結束=======")
 9 
10 class Test(unittest.TestCase):
11 
12     @classmethod
13     def setUpClass(cls):    # 類的前后執行
14         print("測試類開始------")
15     @classmethod
16     def tearDownClass(cls):
17         print("測試類結束=======")
18 
19     def setUp(self):    # 函數的前后執行
20         print("測試用例開始------")
21     def tearDown(self):
22         print("測試用例結束======")
23     def test_case(self):
24         print("我是用例")
25 
26 unittest.main()
示例代碼

 

 

3.Test Runner 執行

通過TextTestRunner類提供的run()方法來執行test suite/test case,test runner可以使用圖形界面、文本界面,或返回一個特殊的值方法來表示測試執行的結果。

  runner = unittest.TextTestRunner()

  runner.run(xxx)

4.Test Fixture 執行前后的操作setUp()和tearDown() 

 1 # -*-coding:utf-8-*-
 2 
 3 import unittest
 4 
 5 def setUpModule():
 6 print("測試模塊開始-------")
 7 def tearDownModule():
 8 print("測試模塊結束=======")
 9 
10 class Test(unittest.TestCase):
11 
12 @classmethod
13 def setUpClass(cls):
14 print("測試類開始------")
15 @classmethod
16 def tearDownClass(cls):
17 print("測試類結束=======")
18 
19 def setUp(self):
20 print("測試用例開始------")
21 def tearDown(self):
22 print("測試用例結束======")
23 def test_case(self):
24 print("我是用例")
25 
26 unittest.main()
View Code

 

 

 

  • 斷言方法

unittest的TestCase類提供下面方法用於測試結果的判斷:

斷言語法 解釋
assertEqual(a, b)  判斷a==b
assertNotEqual(a, b) 判斷a!=b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b)  a is not b
assertIsNone(x)  x is None
assertIsNotNone(x) x is not None
assertIn(a, b)  a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b)

isinstance(a, b)  斷言a是b的一個實例

assertNotIsInstance(a, b) 

not isinstance(a, b)  斷言a不是b的實例

 python的unittest單元測試框架斷言整理匯總  

 

 

  - assertEqual(a , b , msg=None)

斷言第一個參數a和第二個參數b是否相等,如果不等則測試失敗Fail。msg為可選參數,用於定義測試失敗時打印的信息。

 

 

  • TestLoader類

  discover以py文件(模塊)化方式一次執行模塊里所有名為test*的函數。替代了suite.addTest()。

  正常情況下,不需要創建這個類的實例。unittest提供了可以共享的defaultTestLoader類,可以直接使用。

  - unittest.defaultTestLoad.discover(star_dir, pattern='test*.py', top_level_dir=None)

    - 注意:每個文件夾中必須創建__init__.py文件,discover才能識別文件夾里名為test*.py的文件。

 

 1 import unittest
 2 
 3 # discover()方法會匹配指定當前目錄下./的所有test*.py的用例文件,並將查找到的測試用例組裝到測試套件賦在discover中
 4 
 5 test_dir = './'
 6 discover = unittest.defaultTestLoader.discover(test_dir, pattern='test*.py')
 7 
 8 # 直接通過run()方法執行
 9 
10 if __name__ == '__main__':
11 runner = unittest.TextTestRunner()
12 runner.run(discover)
View Code
 
 
 
  • 用例執行順序

unnitest框架默認根據同級目錄下模塊或文件名的ASCII碼的順序來加載測試用例,所以只能通過命名來改變執行順序。除非用TestSuite類的addTest()方法按照別的順序加載。

文件 > 類 >函數

A~Z,a~z,0~9,

例:(當用discover時)

aaa文件夾-testsub.py

testadd.py

  -aaa文件與testadd.py同級,但aaa的ASCII碼<testadd的ASCII碼,所以aaa文件夾-testsub.py要優先於testadd.py!

 

  • unittest如何識別多層目錄?

在每個目錄加上__init__.py文件,就可以識別當前目錄以下的所有文件——一個包是一個帶有特殊文件 __init__.py 的目錄。__init__.py 文件定義了包的屬性和方法。其實它可以什么也不定義;可以只是一個空文件,但是必須存在。如果 __init__.py 不存在,這個目錄就僅僅是一個目錄,而不是一個包,它就不能被導入或者包含其它的模塊和嵌套包。

Python中__init__.py文件的作用詳解 http://www.jb51.net/article/92863.htm

 

 

  • 跳過測試和預期失敗

 

 1 # -*-coding:utf-8-*-
 2 import unittest
 3 
 4 class MyTest(unittest.TestCase):
 5     @unittest.skip("必輸入reason") # 無條件跳過測試,說明原因
 6     def test_skip1(self):
 7         print('直接跳過測試~')
 8     @unittest.skipIf(3>2,"必輸入reason") # 如果條件為真,跳過測試
 9     def test_skip2_if(self):
10         print('條件為真,則跳過測試~')
11     @unittest.skipUnless(3>2,"必輸入reason") # 如果條件為假,跳過測試
12     def test_skip3_unless(self):
13         print('條件為假,則跳過測試')
14     @unittest.expectedFailure   # 不管結果如何,不拋錯
15     def test_excepted_failure(self):
16         self.assertEqual(2, 2)
17 
18 
19 unittest.main()
View Code

 

 

 

  •  保存測試結果報告

打開cmd,到runtest.py模塊的當前目錄,新建文件夾report,輸入:

> python runtest.py >> report/log.txt 2>&1

發現生成了一個report文件夾里的log.txt為結果報告。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM