最新內容已更新至 Blog: 使用 CI 進行自動化測試
Eric
: 完成持續整合與訊息通知後,又向持續發佈的目標前進了一大步。
吉米
: 是啊,完成 CI server 的架設與訊息通告的設定後,就可以立刻確定提供到版控的程式是否能正常建置。
Eric
: 很好,但還不夠。我們下一步就是確保建置出來的軟體,可以正確運行功能。
吉米
: 我們在提供之前的測試,不就是為了確保軟體正確運行功能嗎?
Eric
: 這在軟體規模小的時候還可以,但是如果你手上的軟體己經持續發展六七年以上,還有辦法修改後的程式,每個功能都正常嗎?
吉米
: 確實,通常都是只測試這次修改的功能是否正常,其他功能不太會特別去測試。
Eric
: 對吧!所以這個時間,就要依賴自動測試機制,來檢查原有的功能是否正確運行。
吉米
: 你說的有道理,但我對自動化測試這部份沒有經驗。
Eric
: 沒關係,先跟你說自動化的觀念後,以後,你有機會會用到的。
提到自動化測試,那就一定避不開單元測試。而單元測試最主要的目的,就是 被測試的物件,商業邏輯的是否正確、輸出入的結果是否符合預期。
我們利用單元測試來快速測試、驗證,所開發的功能,是否能達到預期的結果。對於通過測試的功能,至少可以保證它的商業邏輯,在特定的測試的條件是正確無誤的。
而一個好的單元測試,它一定具有 快速、獨立、可重現性、可自我驗證、即時性 這五個特性。通常將這五個特性簡稱為 FIRST 。
而一個好的單元測試,它一定具有 快速、獨立、可重現性、可自我驗證、即時性 這五個特性。通常將這五個特性簡稱為 FIRST 。
Fast 快速
單元測試可以在短時間取得測試結果。
Independent/Isolated 獨立
單元測試時,不需依賴其他的物件或功能,才能進行測試。
Repeatable 可重現的
不管在何時何地,測試的結果應該都是相同的。
Self-Validating 可自我驗證
不管單元測驗通過與否,應該可以從測試工具產生的測試報告,明白的得知測試結果與失敗原因。
Timely 即時
可以當下就知道測試結果。
對於沒有撰寫過單元測試的開發者,往往不知道要從那邊開始下手。或者是手上的程式歷經 N 個人的手,內容過於複雜,無法下撰寫單元測試。
事實上,單元測試的運用與觀念,非常重視 物件導向的特性 與 SOLID 原則。所以,假若不常用或不熟悉物件導向的開發者,初期不容易切入單元測試的世界。
筆者在這部簡單提一下 物件導向的特性 與 SOLID 原則 ,若要進一步了解,網路上也有許多參考資料,就不詳細說明。
物件導向特性
SOLID 原則
單一職責原則(Single responsibility principle, SRP)
每個物件,不管是類別、函數,負責的功能,都應該只做一件事。也因為一次只做一件事,所以它的目的是非常明確的。
相當來說,目的越明確,範圍越小的功能,其單元測試就越容易撰寫。
開放封閉原則(Open-Close principle, OCP)
當功能變改時,該藉由增加新的程式碼來擴充系統的功能。避免修改原本的程式碼來擴充系統的功能。
修改原本正常運行的程式碼,你很難確保這次的變更,是否如預期般,不會影響到其他相關的功能。
就筆者經驗而言,影響到是正常的,沒影響到是運氣好,但通常會對維護上,帶來額外的負擔。
里氏替換原則(Liskov substitution principle, LSP)
簡單來說,只要是繼承父類別的物件。在程式中,只要出現父類別物件的部份,都可以用子類別替換。
接口隔離原則(Interface segregation principle, ISP)
針對不同需求的用戶,開放其對應需求的介面,提供使用。可避免不相關的需求介面異動,造成被強迫一同面對異動的情況。
簡單來說,對不同的用戶,開放不同的功能。再用通俗一點的說法,就是見人說人話、見鬼說鬼話。
依賴反轉原則(Dependency inversion principle, DIP)
類別中,不應該直接使用另一個具有實作類別,而是使用抽象的介面,去承接繼承該介面的實作類別。它的目標就是解除物件與物件間,兩者的直接相依關係。
當軟體規模大到一個程度後,後面的需求變動,往往有很大的機率出現改 A 壞 B的情況。在單元測試保護的情況下,程式改壞了,測試就會直接亮紅燈,以確保程式功能的正確性。
或是軟體需要重構的情況下,確保軟體不會因為程式碼的整理,而造成功能的損壞。
再者時,軟體己具有一定規模時,快速驗證新增功能是否正常,而不需要每次都從重跑流程,造成時間與效率的浪費。
所以 單元測試,真正發揮它的 POWER 的時間點,在於軟體後續長期維護、需求變動、重構時,才能真正的明白為什麼需要單元測試。
在單元測試時,不需要過份追求程式覆蓋率 或 測試案例。
過度追求程式覆蓋率或測試案例,可能會造成無意義的測試案例、或是測試案例維護成本過高的情況。
只需針對 使用頻率最高、曾經出錯的功能 即可。
Eric
: 當我們寫完了自動測試,當然也會希望 CI server 在建置時,順便幫我們確認提交變更後的程式,是否可以通過測試。
吉米
: 嗯嗯,所以我們接著要去 Azure DevOps、Jenkins、Travis CI 這幾個 CI Server 中,設定執行自動測試的動作吧。
Eric
: 沒錯。那我們就接著進行 CI Server 的設定吧。
<<待續>>