單元測試的藝術, 2/e (The Art of Unit Testing: with examples in C#, 2/e)

Roy Osherove 著、陳仕傑(91) 譯

立即出貨 (庫存 > 10)

買這商品的人也買了...

產品描述

不管你是對單元測試或是測試驅動開發的新手,還是已經有豐富經驗的人,都能在這本書裡找到適合自己的內容。
——《無瑕的程式碼》作者 Robert C. Martin(Bob大叔)

《單元測試的藝術》很重要,在好幾年前就應該要有這麼一本書了!
——Michael Feathers

這本書將單元測試所有相關知識解釋地完整透徹。
——連任八屆微軟最有價值專家 陳仕傑(91)


理解如何撰寫單元測試,以及讓它們變得可維護、可讀、可被信任,是這本書的主要內容,不管你使用的是何種程式語言跟編輯器。這本書涵蓋了撰寫單元測試的基本知識,並且講解互動測試的基礎,介紹了在真實世界撰寫、管理和維護單元測試的最佳實踐。

作者簡介

作者 Roy Osherove
從事程式設計已超過15年,他在世界各地擔任顧問及訓練團隊,教導有關單元測試的藝術以及測試驅動開發(TDD)。部落格網址為ArtOfUnitTesting.com。

譯者 陳仕傑(91)
連任八屆微軟最有價值專家(2010~2017)
著作:《ASP.NET MVC 5:網站開發美學》(12刷)、《ASP.NET MVC4 網站開發美學》
譯作:《敏捷開發實踐》
審校:《進入IT產業必讀的200個.NET面試決勝題》
講師:各大技術研討會、知名企業內訓與公開培訓講師、知名部落客

目錄大綱

致謝
第二版 序
第一版 序
譯者序
前言
關於本書
關於封面圖片

PART I 入門

Chapter 1 單元測試基礎
1.1 逐步定義單元測試
1.1.1 撰寫優秀單元測試的重要性
1.1.2 我們都寫過(某種)單元測試
1.2 優秀單元測試的特質
1.3 整合測試
1.3.1 與自動化單元測試相比,非自動化整合測試的缺點
1.4 什麼是優秀的單元測試
1.5 一個簡單的單元測試範例
1.6 測試驅動開發
1.7 成功進行TDD 的三種核心技能
1.8 小結

Chapter 2 第一個單元測試
2.1 單元測試框架
2.1.1 單元測試框架提供哪些東西
2.1.2 xUnit 框架
2.2 LogAn 專案介紹
2.3 NUnit 的第一個步驟
2.3.1 安裝NUnit
2.3.2 載入方案的方式
2.3.3 在程式中使用NUnit 的特性
2.4 撰寫第一個測試程式
2.4.1 Assert 類別
2.4.2 用NUnit 執行第一個測試
2.4.3 增加正向的測試
2.4.4 由紅到綠:測試成功
2.4.5 測試程式風格
2.5 使用參數來重構測試
2.6 更多的NUnit 特性
2.6.1 setup 和teardown
2.6.2 驗證預期的例外
2.6.3 忽略此測試
2.6.4 NUnit 的流利語法
2.6.5 設定測試分類
2.7 測試系統狀態的改變,而非驗證回傳值
2.8 小結

PART II 核心技術

Chapter 3 透過虛設常式解決依賴問題
3.1 虛設常式簡介
3.2 找到LogAn 中對檔案系統的依賴
3.3 如何讓測試LogAnalyzer 更簡單
3.4 重構設計以提昇程式碼的可測試性
3.4.1 擷取介面以便替換底層實作內容
3.4.2 依賴注入:在被測試單元中注入一個假的實作內容
3.4.3 從建構函式注入一個假物件(建構函式注入)
3.4.4 用假物件來模擬異常
3.4.5 透過屬性get 或set 注入假物件
3.4.6 在呼叫方法之前才注入假物件
3.5 重構技術的變形
3.5.1 透過擷取與覆寫直接模擬假結果
3.6 克服封裝的問題
3.6.1 使用internal 和[InternalsVisibleTo]
3.6.2 使用[Conditional] 特性
3.6.3 使用 #if 和 #endif 進行條件編譯
3.7 小結

Chapter 4 使用模擬物件驗證互動
4.1 基於值、狀態與互動的測試
4.2 模擬物件和虛設常式物件的差異
4.3 手刻模擬物件的簡單範例
4.4 同時使用模擬物件和虛設常式物件
4.5 每個測試只用一個模擬物件
4.6 假物件鏈:用虛設常式物件來產生模擬物件或其他虛設常式物件
4.7 手刻模擬物件和虛設常式物件的問題
4.8 小結

Chapter 5 隔離(模擬)框架
5.1 為什麼要使用隔離框架
5.2 動態產生假物件
5.2.1 在測試中使用NSubstitute
5.2.2 用動態假物件來取代手刻假物件
5.3 模擬回傳值
5.3.1 同時使用模擬物件和虛設常式物件
5.3.1.1 驗證物件是帶著某些屬性的情況
5.4 測試事件相關的活動
5.4.1 測試事件監聽者
5.4.2 測試事件是否觸發
5.5 現有的.NET 隔離框架
5.6 隔離框架的優缺點
5.6.1 使用隔離框架時應避免的陷阱
5.6.2 測試程式可讀性變差
5.6.3 驗證了錯誤的東西
5.6.4 一個測試中有多個模擬物件
5.6.5 過度指定的測試
5.7 小結

Chapter 6 深入了解隔離框架
6.1 受限框架和不受限框架
6.1.1 受限框架
6.1.2 不受限框架
6.1.3 基於探查器的不受限框架是如何運作的
6.1.4 框架揭露了不同的探查器能力
6.2 好的隔離框架的價值
6.3 支援適應未來和可用性的功能
6.3.1 遞迴假物件
6.3.2 預設忽略參數
6.3.3 大範圍偽造
6.3.4 假物件的非嚴格行為
6.3.5 非嚴格模擬物件
6.4 隔離框架設計反模式
6.4.1 概念混淆
6.4.2 錄製與重播
6.4.3 黏性行為
6.4.4 語法過於複雜
6.5 小結

PART III 測試程式碼

Chapter 7 測試階層和組織
7.1 執行自動化測試的自動化建置
7.1.1 建置腳本結構
7.1.2 觸發建置和整合
7.2 依據速度和種類對應的測試分類
7.2.1 分開整合測試和單元測試的人為因素
7.2.2 綠色安全區域
7.3 確保測試程式是版本庫管理的一部分
7.4 將測試類別的位置與被測試程式相對應
7.4.1 將測試對應到專案
7.4.2 把測試對應到類別
7.4.3 將測試對應到明確的工作單元入口
7.5 注入橫切面關注點
7.6 為應用程式建立測試API
7.6.1 使用繼承類別繼承模式
7.6.2 建立測試輔助類別和方法
7.6.3 把你的API 介紹給開發人員
7.7 小結

Chapter 8 好的單元測試的支柱
8.1 撰寫可信任的測試
8.1.1 決定何時刪除或修改測試
8.1.2 避免測試中帶著邏輯
8.1.3 每次只測試一個關注點
8.1.4 把單元測試和整合測試分開
8.1.5 用程式碼審查確保程式碼覆蓋率
8.2 撰寫可維護的測試
8.2.1 測試私有或保護的方法
8.2.2 去除重複的程式碼
8.2.3 具可維護性的設計來使用Setup 方法
8.2.4 實作測試隔離
8.2.5 避免對不同的關注點進行多次驗證
8.2.6 物件比較
8.2.7 避免過度指定
8.3 撰寫可讀性高的測試
8.3.1 單元測試的命名
8.3.2 變數命名
8.3.3 有意義的驗證
8.3.4 驗證和操作分離
8.3.5 setup 和teardown
8.4 小結

PART IV 設計與流程

Chapter 9 在組織中導入單元測試
9.1 逐步成為導入變革的領頭羊
9.1.1 準備好面對各種質疑
9.1.2 說服組織內成員:支持者和反對者
9.1.3 找到可能的切入點
9.2 成功之道
9.2.1 游擊式的進行(從下而上)
9.2.2 說服高層(從上而下)
9.2.3 引入外援
9.2.4 讓進度可見
9.2.5 設定具體目標
9.2.6 應對阻礙
9.3 失敗原因
9.3.1 缺乏驅動力
9.3.2 缺乏政策支援
9.3.3 糟糕的實現和第一印象
9.3.4 缺少團隊支持
9.4 影響因素
9.5 質疑和回答
9.5.1 現有流程加入單元測試需增加多少時間
9.5.2 單元測試是否會搶了QA 飯碗
9.5.3 證明單元測試確實有效的方式
9.5.4 單元測試有用的證據
9.5.5 QA 部門還是能夠找到bug 的原因
9.5.6 我們有大量未經測試的程式碼,應該從哪裡開始
9.5.7 我們使用了多種程式語言:單元測試是否可行
9.5.8 軟硬體結合的開發
9.5.9 確保測試中沒有bug 的方式
9.5.10 偵錯器已經證明我的程式沒問題,但還需要測試的原因
9.5.11 測試驅動開發的必要性
9.6 小結

Chapter 10 遺留程式碼
10.1 從哪裡開始加入測試
10.2 決定選擇策略
10.2.1 先易後難策略的優缺點
10.2.2 先難後易策略的優缺點
10.3 在重構前撰寫整合測試
10.4 針對遺留程式碼進行單元測試的重要工具
10.4.1 使用不受限的隔離框架來輕鬆隔離依賴項
10.4.2 使用JMockit 測試Java 遺留程式碼
10.4.3 重構Java 程式碼時使用Vise
10.4.4 重構前使用驗收測試
10.4.5 閱讀Michael Feathers 關於遺留程式碼的書
10.4.6 使用NDepend 來分析產品程式碼
10.4.7 使用ReSharper 瀏覽和重構產品程式碼
10.4.8  使用Simian 和TeamCity 發現重複的程式碼(和bug)
10.5 小結

Chapter 11 設計與可測試性
11.1 為什麼在設計的時候要關心可測試性
11.2 可測試性的設計目標
11.2.1 預設情況下將方法設定為虛擬方法
11.2.2 使用介面導向的設計
11.2.3 預設情況下將類別設計成可繼承的
11.2.4 避免在包含邏輯的方法裡面初始化具體類別
11.2.5 避免直接呼叫靜態方法
11.2.6 避免在建構式和靜態建構式中包含邏輯程式碼
11.2.7 把單例邏輯和單例持有者分開
11.3 可測試性設計的利弊
11.3.1 工作量
11.3.2 複雜度
11.3.3 洩漏敏感的智慧財產權
11.3.4 有時無法進行
11.4 可測試性設計的替代方案
11.4.1 設計爭論與動態型別語言
11.5 難以測試設計的範例
11.6 小結
11.7 更多資源

Appendix A 工具和框架
A.1 隔離框架
A.1.1 Moq
A.1.2 Rhino Mocks
A.1.3 Typemock Isolator
A.1.4 JustMock
A.1.5 Microsoft Fakes(Moles)
A.1.6 NSubstitute
A.1.7 FakeItEasy
A.1.8 Foq
A.1.9 Isolator++
A.2 測試框架
A.2.1 Mighty Moose(又叫:ContinousTests)持續執行器
A.2.2 NCrunch 持續執行器
A.2.3 Typemock Isolator 測試執行器
A.2.4 CodeRush 測試執行器
A.2.5 ReSharper 測試執行器
A.2.6 TestDriven.NET 執行器
A.2.7 NUnit GUI 測試執行器
A.2.8 MSTest 執行器
A.2.9 Pex
A.3 測試API
A.3.1 MSTest API:微軟的單元測試框架
A.3.2 MSTest for Metro Apps(Windows Store)
A.3.3 NUnit API
A.3.4 xUnit.net
A.3.5 FluentAssertion 驗證API
A.3.6 Shouldly 輔助API
A.3.7 SharpTestsEx 輔助API
A.3.8 AutoFixture 輔助API
A.4 控制反轉容器
A.4.1 Autofac
A.4.2 Ninject
A.4.3 Castle Windsor
A.4.4 Microsoft Unity
A.4.5 StructureMap
A.4.6 微軟的託管可擴充框架(MEF)
A.5 資料庫測試
A.5.1 為資料庫進行整合測試
A.5.2 使用TransactionScope 還原(rollback)資料修改
A.6 Web 測試
A.6.1 vonna
A.6.2 Team System web test
A.6.3 Watir
A.6.4 Selenium WebDriver
A.6.5 Coypu
A.6.6 Capybara
A.6.7 JavaScript 測試
A.7 UI 測試(桌面)
A.8 執行緒相關的測試
A.8.1 Microsoft CHESS
A.8.2 Osherove.ThreadTester
A.9 驗收測試
A.9.1 FitNesse
A.9.2 SpecFlow
A.9.3 Cucumber
A.9.4 TickSpec
A.10 BDD 風格的API 框架