code

2017年11月18日 星期六

Software Testing 2 - Autotest and Statement Coverage

節省成本

長期來說,理想上寫一次test case卻能無限多次測試,這是非常節省時間與成本,又增進software robustness的方法。

多人共同開發的必須流程

特別是在agile methods的規範中,一天可能會release several times,每次integration回去main branch一定要經過大量的測試,此時需要auto test cases。


製作Auto test cases的代價

unit test很簡單,也很快速可以寫完,在開發過程就可以順便做完。
function test (integration test)則要花更多時間,因為他是要測試模組間的互動,以及一些code path,所以有時候其實手動測試會比寫一個function test快,視情況而定。

事實上 testing program 也是code,理論上所有開發流程都也該應用在test cases上,包括test the test cases!
不過這樣有點弔詭,理論上寫得夠清楚的話,test cases不需要再被test,要不然不就沒完沒了。

test cases也要被放入一個testing repository,就跟一般的code一樣需要版本管理與維護,這些都是成本!

如果test cases需要時常更改變動,那可能這個project不適合auto test,因為維護成本會大於效益。


Automate 什麼標的?

1. 有testing framework support的語言或是開發環境
2. 很穩定不常變動的requirement / spec
3. 重複性高的測試,regression bugs
4. 人類能力無法勝任的test
5. 多組input data / cross platform tests
6. concurrency
7. 花大量時間者 (可以auto test就跑回家睡覺)


JUnit

JUnit可以寫unit test也可以寫function test,語言當然就是Java,所以叫JUnit。

JUnit提供一些predicates,回傳某些條件的true or false,unit test最好只要測試一個predicate,這樣才能說是"unit test",否則如果使用了兩個以上的predicates,由於第一個predicate failed的話, JUnit就會停止測試這個test,那會讓測試者誤以為整體program的test failure很少的錯覺,因為同一個unit test中的其他的predicates都沒被測試到。


Code Statement Coverage

下圖的default constructor需要兩個test cases,分別測試constructor中的兩個instance variable值是否正確:


注意每個test case應該都只能測試一個值!
為什麼我們要測試這個相當簡單的assignment statement? 因為這是spec,如果未來有人改變了constructor中的assignment,就是違反了spec,則我們的test cases就能抓到!

test cases如下:




以下的second constructor需要四個test cases,分別是執行line32, 36, 39, 40,if statement不需要測試,因為那無法驗證什麼東西:


相對應的test cases如下:





通常我們不需要測試getters,因為他的執行是trivial顯而易見的:


以下這個method事實上只需要一個test case就可以測試所有statements line 59,62,63,65:


因為全部都是連動的。

test case如下:




Branch coverage

branch coverage重點在要執行過所有conditional statement的true / false test,在上面提到的constructor中:


這邊需要4個test cases來測試兩個if,else statement則是跟隨著第一個if被測試了。
如果同時做statement coverage的話(已經測試所有if 為true,以及else為true,共3個branch被covered),我們這邊只需要再做一個test case 來測試第二個if 是false的狀態即可。

同樣的,對以下的method來說,如果已經做了statement coverage,則branch coverage只要再加上一個while condition evaluates to false的condition即可:





Path Coverage

path就是測試所有method最後return的路徑,例如上述的constructor:


有三個paths: 兩個throw statement,以及都沒有throw exception,最後隱性的從Line41 return的path。



Data Coverage

這邊稍微紀錄一下data coverage,主要就是測試spec中的臨界值,光是statement coverage是無法測試到所有的臨界值或是極大小或是特殊值。

沒有留言:

張貼留言