l

2019年2月18日 星期一

透過測試涵蓋率讓重構更有信心(上):分支涵蓋率

Feb. 18 21:49~22:50

▲很多開發環境都內建測試涵蓋率工具,上圖為Eclipse


如何定義程式的行為?

重構(refactoring)是在不改變軟體外在行為的前提下,改變內部結構以改善設計品質。但是問題來了,你怎麼知道你在重構的過程中沒有改變軟體的行為?這個問題,更廣義一點來說,就是你要如何定義軟體的行為?

學過程式語言的人都知道,程式語言有「語法」和「語意」。語法定義結構,語意定義行為。語法錯誤可藉由編譯器(Compiler)幫忙找出,所以開發人員並不會害怕語法錯誤。

但是,整個程式的行為(語意)是由撰寫程式的人所定義,一般來說編譯器是無從得知開發人員的意圖。在開發人員修改程式的過程中,如果不小心改壞掉,原本可以動的程式不能動了,或是出現未被查知的bug,那就很麻煩了。

正規程式語言定義語意的方法過於抽象,大部分的開發人員無法直接運用,退而求其次,實務上開發人員通常透過撰寫測試案例來描述或紀錄程式的行為

***

測試案例足夠嗎?

透過測試案例採用列舉(舉例子)的方式來描述程式行為,就衍生出另一個問題:你怎麼知道你的測試案例足夠多到可以把程式的(主要)行為都表達出來?在傳統軟體測試領域,這個問題叫做測試案例足夠性條件(test case adequacy criteria),常見的方式是透過測試涵蓋率來判別測試案例是否足夠。

今天不是要討論測試,而是要借用測試涵蓋率的觀念,幫助開發人員在重構前判斷測試案例是否足夠支持後續的重構行為。

***

例子

▼你有一個Account物件用來代表客戶的銀行帳戶,你想要重構withdraw函數,但是目前沒有任何測試案例。雖然withdraw程式碼只有短短幾行,但你還是有點害怕萬一重構了之後程式有問題怎麼辦。


▼因此在重構前你準備補寫測試案例,你很快地設計了以下兩個測試案例:


▼接著你觀察withdraw函數的測試涵蓋率,發現第19行分支(branch)呈現黃色,表示還沒被100%涵蓋。


▼於是你繼續增加一個新的測試案例。


▼此時withdraw函數的程式碼全部變成綠色,代表達到100%的分支涵蓋率。

***

下集預告

達到100%分支涵蓋率並不代表測試案例通過程式就沒有bug,換句話說並不表示程式的所有行為都已被測試案例所記錄下來。但這至少是一個在實務上可行且有一定代表意義的涵蓋率,可以當作預備開始重構前的第一個小目標。

下一集將介紹突變測試(Mutation Testing)技巧,可以進一步驗證測試案例的有效性。

***

廣告

對於軟體測試以及軟體重構有興趣的鄉民,可以參考泰迪軟體以下兩個課程:

***

友藏內心獨白:學習測試涵蓋率真的有用。

沒有留言:

張貼留言