iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 30
0
Software Development

【Unit Test】Unit Test with C#系列 第 30

【Day 30】淺談:編寫可靠的測試

即將到了尾聲,這邊繼續談談關於撰寫有關的事情吧。系列開始有談到命名規則,之後有程式架構以及檔案(架構)管理,現在要對於「單元測試」這個程式碼進行說明。
(內容於書本的第八章)


本書作者提到幾個原則和技術:
1.決定何時刪除或修改測試
2.避免測試中有邏輯
3.只測試一個關注的點
4.把單元測試和集成測試分開(個人覺得與第二點和第三點相同)
4.推動程式碼審查

決定何時刪除或修改測試

當單元測試(Unit test)的程式碼寫完後,理論上不會去修改或是去刪除他們,一旦進行更動,表示說我們的測試程式發生問題。
但為什麼會發生問題呢?大概的原因如下:

  • 產品程式碼有缺陷

修改產品的程式碼後,導致我們的測試發生失敗。這是一個正常現象,如果確定我們的測試程式沒有問題,就表示我們抓到臭蟲了,表示我們要修改我們的產品程式,所以這個單元測試達到目的!不用修改Unit test的程式碼。

  • 測試程式碼有缺陷

測試的程式發生問題,當然要修改程式囉!但是測試的程式很難會被發現,因為我們認為Unit test的程式應當都是正確的,所以檢查會先檢測我們的產品程式碼,直到很後面才會到測試的程式碼。
為了確保測試有得到修復,可以進行兩個檢測:確保該Unit test在失敗的時候會失敗,會成功的時候成功。只要達到,這個修復八九不離十了。

  • 語意或是API改變

語意、API改變,首當其衝當然是產品程式碼要做修正,但是只要一改變就要修改程式碼,當然Unit test也是如此,因為有時候呼叫方式不一樣,或是回傳值不同,會造成我們在測試的時候可能因為不正常的呼叫功能,導致錯誤。
所以當API一直更動的時候,不只產品要跟著修改,連Unit test的程式碼也要經常更動。這樣要動很多!什麼都要改兩個部分呀...崩潰

  • 衝突或是無效的測試

在持續開發下,發現有時候客戶的需求有矛盾,或是同樣的功能要減少更多的限制。像是原本的客戶帳號是只有3碼,於是乎我們做出一個Unit test用來測試「檢查客戶帳號剛好3碼」。但是之後發現有些特殊客戶可能帶著識別螞,所以變成4碼,所以就需要測試有四碼的情況。所以現在我們就有檢測「3碼」和「4碼」的Unit test。這時我們就知道客戶的需求有些衝突。
所以當我們滿足「3碼」,「4碼」就會出錯;相同的,滿足「4碼」,「3碼」就會有問題。
因此可以經過這樣的衝突,去確認需求。當確認後就選擇要使用哪個Unit test。

  • 重命名或是重構測試

不可讀的測試產生的麻煩會比解決的問題還要多,它會影響程式碼的可閱讀性,也就會讓別人困惑,導致要花很多時間去閱讀與查找問題。也會降低程式碼的維護性

  • 去除重複代碼

其實這一點可做可不做,因為重複的測試功能有一些好處:越多的測試可能會越容易發現問題,因為用不同人的不同角度看同一件事情,可能因此找到問題。或是有些程式的表達方式比較好,經由那些重複的程式可以提高可讀性。
但是理論上一個就足夠,所以可以適時的刪除,避免被困擾,不然會當測試失敗的時候要找很多程式碼才知道哪邊出問題(這是當程式碼品質參差不齊)。

避免測試中有邏輯

為什麼避免測試中有邏輯呢?首先說說邏輯的定義,就是有條件式(switch、if...else)和迴圈(for、while)。這些邏輯會讓Unit test減少控制的能力。試想,我們跑了1000個迴圈參數,怎麼知道是哪個參數出了問題呢?這樣的測試不可靠,不容易重現,所以不能輕易地鎖定問題。
當然這樣的程式碼會不容易閱讀,因為結構很複雜,加上很難命名,所以無法快速的理解這個測試是要檢測什麼,必須要進入程式碼裡面才能清楚它的測試功能。

只測試一個關注的點

一個Unit test會有一個最終的結果,是一個回傳值、系統改變、第三方的調用。如果我們有多個assert,表示我們有多個判斷,就是我們有多個關注點。當有多個關注點的時候我們無法簡單的命名程式,會降低可閱讀性。重要的是多個assert在執行測試時,當前面的發生錯誤,後面就不會執行。所以當我們認為後面的測試也要執行時,就該變成兩個不一樣的Unit test,不適合放在一起。

推動程式碼審查

作者希望藉由程式碼審查來確保Unit test的覆蓋率。讓所有測試可以通過,並且檢查測試的內容是否沒有錯誤或是遺失。

以上淺淺地談有關於測試程式的編寫概要。希望大家能喜歡


不知不覺30天就結束了,這30天非常的充實與忙碌,感謝大家的收看。
至於暫時卡位的約五六篇文章,將會這幾天陸續補齊,並且會把最完整的程式碼push到github上,屆時大家可以上去看看囉!

之後的文章將會不定期新增。應該會偏向分享文。

這次的ironman eyelash暫時下台,謝謝大家(鞠躬)


上一篇
【Day 29】初談Unit test程式撰寫架構
下一篇
【Day N+1】狀況雜談-測試前需要建置自己的專案
系列文
【Unit Test】Unit Test with C#31

1 則留言

0
joechh
iT邦新手 5 級 ‧ 2018-01-10 09:12:22

恭喜阿!!!

我要留言

立即登入留言