什麼是單元測試?如何做好單元測試?
2019-10-11 19:15
清風軟體測試
閱讀(21462)
評論(0)
編輯
收藏
舉報
什麼是單元測試?如何做好單元測試?
單元測試是指,對軟體中的最小可測試單元在與程式其他部分相隔離的情況下進行檢查和驗證的工作,這裡的最小可測試單元通常是指函數或者類。
單元測試都是以自動化的方式執行,是以在大量回歸測試的場景下更能帶來高收益。
單元測試代碼裡提供函數的使用示例,因為單元測試的具體表現形式就是對函數以各種不同輸入參數組合進行調用。
如何做好單元測試?
1)代碼的基本特征與産生錯誤的原因
無論是開發語言還是腳本語言,都會有條件分支、循環處理和函數調用等最基本的邏輯控制,如果抛開代碼需要實作的具體業務邏輯,僅看代碼結構的話,所有的代碼都是在對資料進行分類處理,每一次條件判定都是一次分類處理,嵌套的條件判定或者循環執行,也是在做分類處理。
如果有任何一個分類遺漏,都會産生缺陷;如果有任何一個分類錯誤,也會産生缺陷;如果分類正确也沒有遺漏,但是分類時的處理邏輯錯誤,也會産生缺陷。
2)單元測試用例詳解
單元測試的用例是一個“輸入資料”和“預計輸出”的集合。需要針對确定的輸入,根據邏輯功能推算出預期正确的輸出,并且以執行被測試代碼的方式進行驗證。即“在明确了代碼需要實作的邏輯功能的基礎上,什麼輸入,應該産生什麼輸出”。
單元測試用例“輸入資料”種類:
- 被測試函數的輸入參數;
- 被測試函數内部需要讀取的全局靜态變量;
- 被測試函數内部需要讀取的成員變量;
- 函數内部調用子函數獲得的資料;
- 函數内部調用子函數改寫的資料;
- 嵌入式系統中,在中斷調用時改寫的資料;
- ……
“預計輸出”:
- 被測試函數的傳回值;
- 被測試函數的輸出參數;
- 被測試函數所改寫的成員變量;
- 被測試函數所改寫的全局變量;
- 被測試函數中進行的檔案更新;
- 被測試函數中進行的資料庫更新;
- 被測試函數中進行的消息隊列更新;
- ……
3)驅動代碼,樁代碼和Mock代碼
驅動代碼是用來調用被測函數的,而樁代碼和Mock代碼是用來代替被測函數調用的真實代碼的。
驅動代碼、樁代碼和Mock代碼三者的邏輯關系
驅動代碼(Driver)指調用被測函數的代碼,在單元測試過程中,驅動子產品通常包括調用被測函數錢的資料準備、調用被測函數以及驗證相關結果三個步驟。
代碼樁(Stub)是用來代替真是代碼的臨時代碼。比如,某個函數A的内部實作中調用了一個尚未實作的函數B,為了對函數A的邏輯進行測試,那麼就需要模拟一個函數B,這個模拟的函數B的實作就是所謂的樁代碼。
僞代碼:
為了實作函數A的全路徑覆寫,你需要控制不同的測試用例中函數B的傳回值,那麼樁函數B的僞代碼就應該是:
當執行第一個測試用例的時候,樁函數B應該傳回true,而執行第二個測試用例的時候,樁函數B應該傳回false。
這樣就覆寫了被測試函數A的if-else的兩個分支。

樁代碼的應用首先起到了隔離和補齊的作用,使被測代碼能夠獨立編譯、連結,并獨立運作。同時,樁代碼還具有控制被測函數執行路徑的作用。
編寫樁代碼通常需要遵守以下三個原則:
- 樁函數要具有與原函數完全相同的原形,僅僅是内部實作不同,這樣測試代碼才能正确連結到樁函數;
- 用于實作隔離和補齊的樁函數比較簡單,隻需保持原函數的聲明,加一個空的實作,目的是通過編譯連結;
- 實作控制功能的樁函數是應用最廣泛的,要根據測試用例的需要,輸出合适的資料作為被測函數的内部輸入。
Mock代碼和樁代碼的本質差別是:測試期待結果的驗證(Assert and Expectiation)。
- 對于Mock代碼來說,我們的關注點是Mock方法有沒有被調用,以書面樣的參數被調用,被調用的次數,以及多個Mock函數的先後調用順序。是以,在使用Mock代碼的測試中,對于結果的驗證(也就是assert),通常出現在Mock函數中。
- 對于樁代碼來說,我們的關注點是利用Stub來控制被測函數的執行路徑,不會去關注Stub是否被調用以及怎麼樣被調用。是以,你在使用Stub的測試中,對于結果的驗證,通常出現在驅動代碼中。
實際項目中如何開展單元測試?
1)并不是所有的代碼都要進行單元測試,通常隻有底層子產品或者核心子產品的測試中才會采用單元測試。
2)你需要确定單元測試架構的選型,這和開發語言直接相關。比如,Java最常用的單元測試架構是Junit和TestNG;C/C++最常用的單元測試架構是CppTest和Parasoft C/C++test;架構選型完成後,你還需要對樁代碼架構和Mock代碼架構選型,選型的主要依據是開發所采用的具體技術棧;
通常,單元測試架構、樁代碼/Mock代碼的選型工作由開發架構師和測試架構師共同決定。
3)為了能夠衡量單元測試的代碼覆寫率,通常你還需要引入計算代碼覆寫率的工具。不同的語言會有不同的代碼覆寫率統計工具,比如Java的JaCoCo,JavaScript的Istanbul。
4)最後你需要把單元測試執行、代碼覆寫率統計和持續內建流水線做內建,以確定每次代碼遞交,都會自動觸發單元測試,并在單元測試執行過程中自動統計代碼覆寫率,最後以“單元測試通過率”和“代碼覆寫率”為标準來決定背刺代碼遞交是否能夠被接受。
在項目中全民推行單元測試時,你會發現還有一些困難需要克服:
1)緊密耦合的代碼難以隔離;
2)隔離後編譯連結運作困難;
3)代碼本身的可測性較差,通常代碼的可測試性和代碼規模成正比;
4)無法通過樁代碼直接模拟系統底層函數的調用;
5)代碼覆寫率越往後越難提高。
-
分類 軟體測試
, 自動化測試
- 标簽 單元