敏捷之旅高雄那天, 正在去會場時有位網友問了單元測試的問題, 他對於名詞解釋有些疑惑, 因此, 我花了些篇幅來解釋, 順便也分享給大家.
 
問題:
老師好,我是您在資策會軟體測試課程的學生。 想請問若公司沒有所謂的 spec, 但 RD 卻能摸索出個什麼東西,有實際可以 demo 的 app,功能許多並可以與網路 api 連結,資料可以互通的情況下,我們要實施測試,單元測試,整合測試。 我的疑問是黑箱單元測試(或整合測試) 能不看程式碼設計嗎?因為單元測試需要設計 Test double,不可能不知道黑箱內部有什麼相依元件需要替換。 這名詞上的疑問,黑箱單元測試可以看程式碼,會是黑箱還是灰箱,白箱呢?那麼白箱單元測試也需要安排 Test double 嗎?
 
 
我的想法:
單元測試
主要針對一個單元 (funciton, class) 來進行測試者, 可稱為單元測試.
 
黑箱測試
根據程式行為來做測試, 不在乎內部程式結構.
例如: IsTrangle( int a, int b, intc ), 用黑箱測試的話, 會這樣進行
IsTrangle (2, 3, 4)
IsTrangle (-1, 3, 4)
 
===> 這裡就是你所謂的黑箱單元測試(或整合測試), 你可能根據程式 API 文件說明, 就知道要輸入什麼資料, 就可以進行測試. 不用管程式碼怎麼寫. 就像你在網路上抓 open source library 來用, 你有在看人家內部程式怎麼寫嗎?
 
白箱測試
要根據程式內的結構進行測試者, 我們稱為白箱測試. 那程式內有什麼結構呢?不外乎就是 if, while, for 或者是變數的使用. 因此白箱測試的方法有以下幾種
(1) date flow coverage (變數使用的狀況都要測到)
(2) branch coverage (每個程式邏輯分支都要測到)
(3) statement coverage (每個程式敘述都要測到)
….
 
「white box black box」的圖片搜尋結果
 
 
 
假設 IsTrangle 的程式長得如下:
1: bool IsTrangle (int a, int b, int c) {
2:     if ( a<= 0 or b <=0 or c <= 0 )
3:         return false;
4:     if ( a + b > c or a + c > b or b+c > a)
5:        return true;
6:     return false;
7: }
 
你要先根據程式結構, 找出你要處理的路徑, 例如我想要經過所有分支, 所以我會測以下路徑
(路徑1) 1 -> 2 -> 3
(路徑2) 1 -> 2 -> 4 -> 5
(路徑3) 1 -> 2 -> 4 -> 6
 
找出路徑之後, 我們會對每條路徑開立測試個案:
(路徑1) IsTrangle (-1, 2, 3)
(路徑2) IsTrangle (3, 4, 5)
(路徑3) IsTrangle (1, 2, 8)
 
============================================
 
剛剛講的狀況可能是這個單元不會用到別人, 但是當受測單元會用到別人時, 你需要寫 Test double 之類的東西, 來取代受測單元會呼叫到的程式. 例如以下狀況:
 
test program —> 受測單元 A ——> 函式 B
 
這時候如果要進行單元測試, 你會改成
 
test program —> 受測單元 A ——> test double B
 
「testdouble」的圖片搜尋結果
 
 
不錯, 這時候你會去看看 受測單元 A 的程式碼, 然後才知道要如何寫 test double B. 可是 .....
 
接下來測試時, 你會根據受測程式的內部結構來開測試個案嗎? 就像前面我講白箱測試那段, 如果不會, 我覺得他不算是 pure 白箱, 因為他沒根據程式結構開立測試個案, 他可能還是根據受測程式行為開個案. 目前 IsTrangle 這個程式還小, 你可能會看一下程式碼, 一班我們在寫的程式, 可能也有 100-200 行, 所以絕大多數人是不會去根據程式結構做處理, 只會很快根據程式行為開一開.
 
硬要扯的話, 勉強說是 gray box testing. 結合了部分白箱, 部分黑箱. 
 
 
所以不需要把 單元測試 和黑箱白相掛鉤, 基本上單元測試你可以用黑箱方法 和 白箱方法. 黑箱或白箱也可以搭配 test double, 差別只是怎麼開立測試個案.
 

    全站熱搜

    kojenchieh 發表在 痞客邦 留言(1) 人氣()