1. 程式人生 > >測試框架Unitest的執行原理,以及多個測試類中的執行順序以及簡化方法

測試框架Unitest的執行原理,以及多個測試類中的執行順序以及簡化方法

單元測試單元測試(unit testing)是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義,如C語言中單元指一個函式,Java裡單元指一個類,圖形化的軟體中可以指一個視窗或一個選單等。總的來說,單元就是人為規定的最小的被測功能模組。單元測試框架在單元測試框架出現之前,開發人員在建立可執行測試時飽受折磨。最初的做法是在應用程式中建立一個視窗,配有"測試控制工具(harness)"。它只是一個視窗,每個測試對應一個按鈕。這些測試的結果要麼是一個訊息框,要麼是直接在窗體本身給出某種顯示結果。由於每個測試都需要一個按鈕,所以這些視窗很快就會變得擁擠、不可管理。
單元測試框架提供了一種統一的程式設計模型,可以將測試定義為一些簡單的類,這些類中的方法可以呼叫希望測試的應用程式程式碼。開發人員不需要編寫自己的測試控制工具;單元測試框架提供了測試執行程式(runner),只需要單擊按鈕就可以執行所有測試。利用單元測試框架,可以很輕鬆地插入、設定和分解有關測試的功能。測試失敗時,測試執行程式可以提供有關失敗的資訊,包含任何可供利用的異常資訊和堆疊跟蹤。不同程式語言有不同的單元測試框架,如Java Junit, TestNg, c# Nunit,Pythonunittest,Pyunit,testtools, subunit....
  • 一個TestCase的例項就是一個測試用例。
  • 什麼是測試用例呢?就是一個完整的測試流程,包括測試前準備環境的搭建(setUp),執行測試程式碼(run),以及測試後環境的還原(tearDown)。
  • 元測試(unit test)的本質也就在這裡,一個測試用例是一個完整的測試單元,通過執行這個測試單元,可以對某一個問題進行驗證。
  • 而多個測試用例集合在一起,就是TestSuite,而且TestSuite也可以巢狀TestSuite。
  • TestLoader是用來載入TestCase到TestSuite中的,其中有幾個loadTestsFrom__()方法,就是從各個地方尋找TestCase,建立它們的例項,然後add到TestSuite中,再返回一個TestSuite例項。
  • TextTestRunner是來執行測試用例的,其中的run(test)會執行TestSuite/TestCase中的run(result)方法。
  • 測試的結果會儲存到TextTestResult例項中,包括運行了多少測試用例,成功了多少,失敗了多少等資訊。
  • 那什麼是test fixture呢?
  • Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.
可見,對一個測試用例環境的搭建和銷燬,是一個fixture,通過覆蓋TestCase的setUp()和tearDown()方法來實現。這個有什麼用呢?(1)比如說在這個測試用例中需要訪問資料庫,那麼可以在setUp()中建立資料庫連線以及進行一些初始化,在tearDown()中清除在資料庫中產生的資料,然後關閉連線。注意tearDown的過程很重要,要為以後的TestCase留下一個乾淨的環境。(2)關於fixture,還有一個專門的庫函式叫做fixtures,功能更加強大,以後會介紹到。unittest執行原理



那一個測試類裡面,如果寫了多個方法,最終算是多個測試用例呢?還是一個測試用例呢?(1)對每一個以test開頭的方法,系統都為其構建了一個TestCase物件,系統也只執行TestCast物件的方法。(2)如果沒有定義test開頭的方法,而是將測試程式碼寫到了一個名為runTest的方法中,那麼會為該runTest方法構建TestCase物件,如果定義了test開頭的方法,就會忽略runTest方法。(3)至此,基本就清楚了,每一個以test開頭的方法,都會為其構建TestCase物件,也就是說TestSequenceFunctions類中其實定義了三個TestCase,之所以寫成這樣,是為了方便,因為這幾個測試用例的fixture是相同的,如果每一個測試用例單獨寫成一個TestCase的話,會有很多的冗餘程式碼。(4)上圖中,assertTrue_test這個是斷言方法,最終程式如果按照Unittests方式去執行,斷言方法是不會被執行的有關TestCase構造的詳細方法,可以參考原始碼解析,參考網址為:3.unittest常用的斷言方法
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)
assertNotIsInstance(a, b) not isinstance(a, b)
(1)使用unittests方式去執行程式,最終顯示斷言方法沒有被執行,因為系統預設去執行test開頭的方法(2)一般,在自動化單元測試中,一般把斷言放在測試用例方法中,去判斷結果,而不是單獨寫一個斷言方法 

4.Unittests中如果定義了多個類,每個類中也有多個方法,那麼執行的順序是怎樣的?




總結:(1)最終主程式先執行哪個類、是按照這個類的名字字母、以及資料排序的(2)最終,先執行哪個方法,是按照某類中,方法的名字、數字排序的(3)主程式中先載入哪個方法,或者後加載哪個方法,在unittests執行的模式下,沒有任何作用(4)只有當使用普通模式下執行這個程式,才會按照順序去執行。 

5.如何才能簡化如上的程式?以下程式是上如程式的類似簡化版本