參考資源 :
首先何謂單元測試、整合測試? 那這邊我認為主要的差別就是你所測試的對象是否有跟其他資訊整合。(例如 : 時間、DB、Service、Config。 這些會因為不同環境或配置就影響到單元測試的成敗,這就可以歸類為整合測試)
單元測試需要必備基本功 :
- 了解單元測試框架、隔離框架。
- 如何設計可測性的代碼。
- 對於測試腳本撰寫以及規範。
- 以及透過 Code Coverage 去分析測試代碼是否有遺漏。
單元測試框架主要具備 :
- 撰寫結構化的測試
- 執行一個或全部單元的測試
- 確認執行結果
那目前有接觸過的單元測試框架 : MSTest 、 NUnit。
它們主要透過 attribute 來標示那些需要進行單元測試、然後會提供一個執行器去執行你的單元測試腳本、最後會返回測試結果和報表。
隔離框架 :
- 非受限隔離框架
- 受限隔離框架
這兩類差異主要是針對 fake 的程式可以掌握程度不同,而目前我有接觸的是 Nsubstitute 受限隔離框架。(Free、document 完善、不能伪造靜態方法、非虛擬方法、非公開方法等等等。
為什要需要隔離框架呢 ?
主要是透過隔離框架可以漸少我們手刻類別,我們可以用 framework 提供的方法,可以迅速針對介面定義方法去控制,並且指定預期的結果。(以往我們需要先在測試專案實作介面)
關於可測試性的代碼
- 移除重複代碼。(相對減少重複的測試代碼)
- 一個 method 主要關注一件事。(會使測試代碼相對單純、清楚)
- 透過 DI、IOC 讓我們可以控制方法內部的那些相依。(去相依,透過 fake 把指定代碼注入的測試代碼之中,只專注測試代碼本身的邏輯處理。)
- 相同業務移到正確位置。(避免過多注入行為)
測試腳本的規範
- 3A (arrange、assert、act)
- 不要濫用 TestInitialize、CleanUp。(除非要初始數據,否則會導致每個腳本都需要關注、並且由於分散你必須要每次滾動到最上面去進行確認,這邊應該要包共用、工廠方法去解決重複代碼的部分,而不是依賴 TestInitialize、CleanUp)
- 測試腳本不要撰寫過多邏輯。(不要產生一些動態程式、或者一些 if else 的條件判斷,這邊會導致你需要確認你的測試邏輯那邊是否正確)
- 測試場景不要共用。(兩個測試場景共用、可能會因為前面方法失敗而影響到現有的測試腳本)
- 一次只驗證一個行為。(過多的 assert 會導致你不能快速瞭解那些出錯,以及導致測試方法不單純)
- TestMethod 命名 : 測試方法_測試場景_預期結果。(Team 一致的風格、並擁有可讀性)
- 測試專案與被測試專案分開。(命名建議 XXX.proj -> XXX.UnitTest.proj 、 XXX.cs -> XXXUnitTest.cs,透過此方式能讓我們迅速找到對應的程式)
- 保持測試腳本獨立性、不該強制控制腳本執行順序。(如果有靜態屬性、或者 flag 需要再執行腳本完後還原到原本狀態)
透過 Code Coverage 去分析測試腳本
- 對於被測試方法的測試覆蓋度,以提高測試程式的可靠性;
- 並且 Code Coverage 以 70 ~ 80% 為基本標準,過高的覆蓋度可能會造成時間的浪費,而應優先覆蓋最重要的功能點、或最多被參考使方法為優先。
而日常工作上會遇到團隊導入單元測試的困境,例如 : 代碼不好寫單元測試、團隊沒有共識、為何要寫單元測試、沒有時間寫單元測試的問題,這都是導入單元測試一個大問題。
而這邊主要紀錄這邊對單元測試的體悟,對於網上資源豐富就不撰寫相關範例。(對於單元測試主要就是觀念、以及如何高效率撰寫單元測試和會說話的測試腳本)
如果要了解細節部分、或者延伸相關 TDD、BDD 的部分,可以看 單元測試的藝術 以及多上 91 大大的課程學習。
如果有任何錯誤或者引用問題請麻煩告知 !!!