發表文章

探討單元測試和整合測試的涵蓋範圍

圖片
本篇文章紀錄自己導入 測試驅動開發(Test Driven Design) 過程中,曾經沒辦法分辨自己所寫的測試案例到底是“單元測試”還是“整合測試”,與同儕討論後發現其他人也有相同的困擾,於是看了幾本書與文章才釐清自己的問題所在。為方便與其他人進行交流討論,故將自己理解的資訊整理下來並做個總結。 單元測試的涵蓋範圍很模糊? 單元測試(Unit Test)是軟體開發中很重要的環節,替 TDD 提供重構的保護網,也是軟體測試(Software Testing)中測試金字塔(Test Pyramid)的最低測試層級。 但是,一個「單元測試」所涵蓋的範圍到底有哪些,卻讓國外網友議論紛! 大家在初學單元測試一定會看到的定義如下: 以程式碼的最小單位來進行正確性檢驗的測試工作,最小單位包括「類別與方法」。 若按此定義來寫測試案例,一個單元測試只能包含一個類別。且受測類別的依賴都必須透過測試替身或 Mock 技術進行隔離,才能確保測試的目標是最小且不可分割的邏輯。 但是隨著 Mock 的詬病被發掘(參考: Mock 不是測試的銀彈 ),為避免 Mock 使測試案例變成開發人員的快樂表(測試通過,正式環境卻出現錯誤),開始有人提倡使用 Spy 來替代 Mock,以及依賴若是自己的開發團隊所寫,而非第三方函式庫,則可直接使用依賴。 這時,一個單元測試會執行的範圍已經從 一個類別 變成 一個類別加上該類別的依賴 。換句話說,一個單元測試除了受測程式外,也會執行到其他類別的程式碼: describe( 'AddGroupToRange' , function () { it( '空的統計範圍, 將題組「questionGroups1」新增至空的統計範圍中, 統計範圍包含題組「questionGroups1」' , function () { // @given 空的統計範圍 var range = new StatisticsRange(); var pipeline = new Pipeline(range); // @when 將題組「questionGroups1」新增至空的統計範圍中 pipe

設計模式起手式:介面(Interface)

圖片
在閱讀經典書籍《 設計模式 Design Patterns 》中,如果你跳過第 1 章引言,那你可能就錯過了設計模式的核心概念了!作者在引言中花了大篇幅講解 介面 在物件導向設計中的定位,以及設計模式如何透過 介面 來解決問題。

PHP CodeIgniter 3 單元測試日常:建立 PHPUnit 測試環境

圖片
本文將帶領讀者建立 CodeIgniter 3 框架的 PHPUnit 測試環境,給 CodeIgniter 3 一個現代化的機會! 本文假設您已經具備 軟體測試自動化 以及 PHPUnit 相關知識,且了解如何撰寫測試案例。若您尚未了解單元測試或軟體測試自動化,這裡提供一些不錯的資源讓您初步了解: otischou.tw:瞭解單元測試 阿川先生:先寫單元測試的12個好處! 除了上面兩個資源外,請您務必花時間認識並學習軟體測試,這可以說是軟體開發技術的核心技能之一。 若您尚未了解 PHPUnit 這裡也有些簡單的文件供您參考: PHPUnit 官方中文文件 Jace Ju:PHPUnit 入門介紹 前言 2020 年對於 PHP 界風靡一時的 MVC 框架「CodeIgniter」來說,光環已經被新星 Laravel 搶去。雖然 CodeIgniter 的討論熱度已經消退了,但市佔率仍然相當高,至今仍有許多 PHPer 還在與 CodeIgniter 奮鬥和成長(包括我)。 由於 CodeIgniter 3 框架(以下簡稱 CI3)沒有使用 Namespace 的特性,加上 CI3 統一透過框架內建的 Loader 類別實現 Autoload 機制,造成很多 PHPer 沒辦法在 CI3 框架中使用現代 PHP 的特性來開發系統。若不做點手腳的話,PHPer 的開發思維很容易就會被 CI3 框架綁架,一不小心就將所有業務邏輯全部寫在 CI3 框架中。換句話說所有的程式碼都依賴於框架,物件導向 SOLID 原則的實現、設計模式、單元測試 …等較進階的管理程式碼策略都不用談了! 為了讓還在與 CI3 奮鬥的同袍們能夠使用現代 PHP 的特性來開發系統,本文將介紹如何在 CI3 框架中建立單元測試的環境,讓 CI3 也能使用並測試現代 PHP 的程式碼,確保 PHPer 能安心地實現各種開發策略和思維。 導入 Composer 擁抱現代 PHP 特性 其實 CI3 跟現代 PHP 只差臨門一腳,你可以在 config/Config.php 中找到一個設定為 composer_autoload ,只要替 composer_autoload 設定 Composer 目錄底下的 autoload.php 路徑,你的

2019 回顧工作與學習歷程

圖片
2019 回顧前言 2019 年可以說是既充實又偷懶的一年。為什麼呢?因為花了很多時間在學習理論知識,包含:重構、整潔架構、單元測試、領域驅動開發、行為驅動開發 …等等。雖然每個知識看起來像是完全獨立的領域,但對 2019 的我來說,它們都是應付 Legacy Application 的利器。 為什麼又說偷懶?部落格和作品幾乎停擺!學習知識理論不像學習新技術,能把應用新技術的步驟分享到部落格上。因為理論知識必須經過堆疊和內化才能在真實專案中落地實踐。再加上這一年很 榮幸受邀到高雄科技大學,帶領一批資工系的學生學習 PHP 式設計課程 ,備課與上課的時間幾乎吃掉了三個月的休閒時間,也就是平常能用來自學或練習的時間 …

物件導向設計原則:里氏替換原則,定義、解析

圖片
里氏替換原則(Liskov Substitution Principle) 定義 Subtypes must be substitutable for their base types. - 子類別必須能取代父類別 里式替換原則是從 開放封閉原則 延伸出來的原則,若對開放封閉原則還不了解,建議先去瞭解開放封閉原則如何透過引入抽象來擴充程式碼的行為,再來學習里氏替換原則!

物件導向設計原則:開放封閉原則,定義、解析與實踐

圖片
系列文章 淺談物件導向 SOLID 原則對工程師的好處與如何影響能力 再談 SOLID 原則,Why SOLID? SRP 單一職責原則,定義、解析與實踐 物件導向設計原則:開放封閉原則,定義、解析與實踐 開放封閉原則(Open-Closed Principle) 定義: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. -- 軟體中的類別、模組、函式等等應該開放擴充,但是封閉修改。 白話版本為: 當系統需要擴充功能時,應該藉由 增加新的程式碼 來擴充系統的功能,而 不是藉由修改原本已經存在的程式碼 來擴充系統的功能。 開放封閉原則為軟體開發的 首要原則 ,很多軟體開發原則都是建構在這短短一句話之上,因此可以通過此原則引伸出其他原則。很多時候一個程式具有良好的設計,往往說明它是符合開放封閉原則。 目的 隔離業務邏輯與附加邏輯,使業務邏輯更易於擴充,以便因應需求變化。 解析 什麼是業務邏輯?附加邏輯? 一個系統總有幾個極具價值的核心邏輯,這些核心邏輯實現了企業或專案的業務規則(Business Rule)與 Know How。通常可以從核心邏輯延伸出更多功能,提供使用者的便利性,以下將這些核心業務邏輯簡稱為「業務邏輯」。也就是說系統中有可能 20% 是業務邏輯 ,剩下的 80% 是圍繞著業務邏輯延伸出來的附加邏輯 。 舉例來說,一個診所掛號系統一開始只有「掛號與叫號」功能。但若需要的話,也可以延伸出「叫號時發送簡訊提醒患者」功能。掛號系統的案例中 業務邏輯 是「掛號與叫號」;而「叫號時發送簡訊提醒患者」則是 隨著時間與新需求延伸出來的附加邏輯 。 為什麼要隔離 業務邏輯 與 附加邏輯? 和軟體複雜的特質 軟體熵(Software entropy) 有關,指系統在經過修改後,程式碼的無序程度(意圖流失程度)與複雜程度皆會上昇。 需求變更和除錯是系統修改的主因,系統會隨著時間不斷衍生出新需求。這些需求可能是工程浩大的新功能;也可能是為了某個特定案例只使用一次的需求。甚至客戶往往在看見實際功能後,才想