測試涵蓋度 是一個有趣的話題, 很多人不了解他, 常常對它有神奇的幻想. 今天我們就來好好聊聊它
 
測試涵蓋度 (testing coverage) 是用來度量程式中元素, 經過測試後被涵蓋的程度.
 
例如: 你寫了 2 個函式 (如下面程式片段所示), 你測試了函式 funA, 我們就可以說測試涵蓋度是 1/2 % = 50%. 這裡我們的元素是指函式.
 
 
void funA( int a, int b, int c) {
    if (a < 0 || b < 0 || c< 0 ) {
        printf (“不是三角形”);
        return;
    }
    if ( (a == b) && (b == c) ) {
        printf (“正三角形”);
        return;
    }
}
 
void funB ( int a, int b, int c) {
     printf( “正三角形”);
}
 
 
我想很多人聽過 line (statement) coverage, branch coverage, decision coverage. 這就是他們是在計算不同元素被涵蓋的程度. 上面範例是計算函式這個元素被涵蓋的狀況.
 
如果是 line (statement) coverage 的話, 直接呼叫 函式 funB, 立馬就可以達成 100% line coverage.
函式 funA 要達到 100% line coverage, 就比較麻煩. 你需要準備 2 組 test cases.
(1) a = -1, b =-1, c = -1
(2) a = 3, b = 3, c = 3
這樣你才能經過函式 funA 內每一行程式碼.
 
但是如果要經過函式 funA 所有 branch, 你便要經過以下 4 個 branch
(1) 要讓 if (a < 0 || b < 0 || c< 0 ) 是 true
(2) 要讓 if (a < 0 || b < 0 || c< 0 ) 是 false
(3) 要讓 if ( (a == b) && (b == c) ) 是 true
(4) 要讓 if ( (a == b) && (b == c) ) 是 false
 
這時候你要準備以下 3 組 test cases. 這樣才能達到 100% branch coverage
(a) a = -1, b =-1, c = -1
(b) a = 3, b = 3, c = 3
(c) a = 3, b = 2, c = 3
 
類推, 如果要經過函式 funA 所有 decision, 你需要經過以下 12 個組合, 這樣才能達到 100% decision coverage
(1) if (a < 0 || b < 0 || c< 0 ) {
a < 0 
b < 0
c < 0
true
true
true
true
true
false
true
false
true
true
false
false
false
true
true
false
true
false
false
false
true
false
false
false
 
(2) if ( (a == b) && (b == c) ) {
 
a == b
b == c
true
true
true
false
false
true
false
false
 
所以你挑的元素會決定涵蓋度的代價的多寡, 選 decsion 就要比 line 多測好幾個 test case. 由下表你可以知道, 最下面的 statement (line) coverage 是代價最少的, 越往上越恐怖. All paths 是不可能做到.
 
 
 
 
那你還觀察到什麼嗎?
 
(1) 選擇什麼元素來計算涵蓋度很重要
 
如果你選擇的元素是函式, 那就很容易可以達到 100%, 可是如果是選擇 decision, 那就有點難度. 
 
可是, 通常很多人不知道, 看到你有測試涵蓋度就高潮了, 外加看到你還說涵蓋度的值接近 100% 就會再次高潮. 
 
根據 業界經驗, function coverage 或是 line coverage 只要有做, 出現 70-80% 以上是很正常的 (你用到 3rd party codes 不算的話). 要到達 90% 以上才算是工程師有額外花心思在做.
 
所以看到涵蓋度的值很高, 先不用太高興, 要先看度量的元素是什麼.
 
 
(2) 測試涵蓋度只是告訴你那幾行沒經過, 但是涵蓋度的值跟品質無關
 
達到 100% 涵蓋, 程式品質就好嗎? 當然不是. 測試涵蓋度高, 不代表品質沒問題.
 
例如前面舉例函式 funA 要達到 100% line coverage, 你要準備下面兩組資料
a = -1, b =-1, c = -1
a = 3, b = 3, c = 3
 
測試過後你就會得到 100% line coverage, 可是程式還是有 bug. 因為 a, b, c 其中有一個是 0, 他應該也不是三角形. 
 
測試涵蓋度只是告訴你那幾行沒經過, 或是那幾行經過. 但是沒他告訴你, 是用哪些測試資料經過這些地方. 不同測試資料可以經過相同程式碼, 但是有些會抓到 bug, 有些不會抓到 bug.
 
 
(3) 測試涵蓋度高不代表程式寫得好
 
例如 函式 funB 他很容達到 100% line coverage or 100% branch coverage. 因為他都不寫任何檢查. 
 
所以你如果拿 coverage ratio 當 KPI, 那 RD 就會少寫很多 error handling, 這樣他的程式才很容易達到 100% line coverage.
 
 
 
所以, 看到涵蓋度不用想太多, 他只告訴了你哪些地方經過或沒經過, 所以你可以用來決定要不要補 test cases.
 
並且千萬不要認為涵蓋度高就是品質好, 就是測試做足夠了. 沒有絕對的關係.
 
 
 
 
 
 
 
 
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 kojenchieh 的頭像
    kojenchieh

    David Ko的學習之旅

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