關於unittest模塊的一些心得,主要是看官網的例子,加上一點自己的理解,官網地址:https://docs.python.org/3.6/library/unittest.html
基礎概念介紹:
unittest模塊是Python的單元測試框架,支持自動化測試,所有用例共享setUp和tearDown代碼,可以將測試用例聚合成測試集合,測試用例與報告框架獨立。
為了實現這些功能,unittest支持下面幾個面向對象式的概念:
- test fixture:代表了執行一個或多個測試用例所需要的准備工作,以及所有相關的清除工作。比如創建臨時的或者代理的數據庫,文件夾或者啟動服務器。
- test case: 代表了一個單獨的單元測試用例,會檢查輸入參數對應的反饋。unittest提供了一個基類TestCase用來創建測試用例。
- test suite: 代表了測試用例及測試套件的集合,用來將測試用例聚合到一起去執行。
- test runner: 用來執行測試用例並將測試結果反饋給用戶。可以用圖形接口,文字接口或者返回一些指定值來指示測試結果。
- test report: 可以使用unittest自帶的TextTestRunner(),也可以使用HTMLTestRunner()產生HTML格式的測試報告,現在用BSTestRunner()代替HTMLTestRunner()
這些概念間的關系見下圖:
下面給一些例子和說明:
import unittest ###編寫的測試類要繼承unittest.TestCase,類名稱要以test開頭,后面講原因。 class TestStringMethods(unittest.TestCase): ###所有用例共用的setup,在用例執行前先執行,用來搭建環境。 def setUp(self): print('case setup') ###所有用例共用的tearDown,在用例執行結束后執行,用來清理環境。setUp和tearDown保證了每個test case都是獨立的,不依賴與其他case. def tearDown(self): print('case teardown\n') def test_upper(self):###測試用例1,需要以test開頭,原因后面講。 print('case test_upper') self.assertEqual('foo'.upper(), 'FOO')###assertEqual(a,b)如果a==b則用例pass,否則fail. def test_isupper(self):###測試用例2,需要以test開頭。 print('case test_isupper') self.assertTrue('FOO'.isupper())###類似的assert用法 self.assertFalse('Foo'.isupper()) def test_split(self):###測試用例3 print('case test_split') s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # check that s.split fails when the separator is not a string with self.assertRaises(TypeError): s.split(2) if __name__ == '__main__': unittest.main()###具體做了哪些工作后面會詳細講。
下面看一下case的運行結果:
case setup case test_isupper case teardown case setup case test_split case teardown case setup case test_upper case teardown ###三個case全部pass,因為assert里面的結果都正確。這里並沒有體現出測試結果,只是將打印信息展示出來。我們可以看到針對每個test_的case都運行了一遍,每次都獨立的調用了setUp和tearDown.測試case執行的順序不是按照代碼的順序,而是按照case名稱字母的順序,這個是unittest.main()函數決定的。
命令行模式:
unittest模塊可以通過命令行模式從模塊,類,或者類的方法中運行測試用例。我使用的也不多,給出最基本的例子。
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass python -m unittest test_module.TestClass.test_method
跳過某些測試用例:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping") def test_nothing(self): print("shouldn't happen") @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") def test_windows_support(self): # windows specific testing code print('this is Windows') pass
類似的@unittest.skip()裝飾器包括:
@unittest.skip(reason)
#直接跳過這條測試用例,需要給出跳過的理由
@unittest.skipIf(condition, reason) #跳過這條用例,如果condition值為True @unittest.skipUnless(condition, reason) @unittest.expectedFailure exception unittest.SkipTest(reason)
@unittest.skip()可以用來裝飾類的方法,也可以用來裝飾class,將這個class全部跳過.