Code Monkey home page Code Monkey logo

books's People

Contributors

fntsrlike avatar

Stargazers

 avatar

Watchers

 avatar  avatar

books's Issues

陶晉生,《宋遼金元史新編》

基本資料

  • 系列名:史學叢書系列58
  • ISBN13:9789866913419
  • 出版社: 稻鄉
  • 作者:陶晉生
  • 出版日:2008/09/01

作者介紹

陶晉生(Jing-shen Tao,1933年-),祖籍湖北黃岡,臺灣歷史學家、**研究院院士,專攻宋遼金元史。為國立臺灣大學歷史系學士、歷史研究所碩士、美國印第安那大學歷史系博士。曾任臺大歷史系教授、**研究院歷史語言研究所研究員、美國亞歷桑那大學教授、香港中文大學講座教授。現任中研院史語所通信研究員、東吳大學歷史學系客座教授。[1]曾主持《食貨月刊》、《新史學》等歷史雜誌。

詳細參見維基

AoE2HD

本主題紀錄一些世紀帝國的學習資源,並在回覆中書寫紀錄檔觀看筆記與戰報。

王順鎮,《竹林七賢》三冊

基本資料

  • 作者: 王順鎮
  • 出版社:實學社
  • 出版日:1998/08/01

作者

王順鎮筆名洪川,既是劇作家、又是小說家。他創作的歷史劇《魂斷燕山》、《燭影搖紅》,歷史小說《長河落日》、《竹林七賢》、《謝安》等數百萬字作品,暢銷7個國家和地區,好評如潮。

詳見百度百科

Roy Osherove, "The Art of Unit Testing"

我看的是由金迎翻譯的簡中譯本,名稱為《單元測試的藝術》,由人民郵電出版社出版。

章節

  1. 單元測試的基礎
  2. 第一個單元測試
  3. 使用存根破除依賴
  4. 使用模擬物件進行交互測試
  5. 隔離(模擬)框架
  6. 深入了解隔離框架
  7. 測試層次和組織
  8. 優秀單元測試的支柱
  9. 在組織中引入單元測試
  10. 遺留程式碼
  11. 設計與可測試性

延伸閱讀:

  • Robert C. Martin, Clean Coder
  • Bill Hetzzel, The Complete Guide to Software Testing (Wiley, 1993)
  • Michael Feathers, Working Effectively with Legacy Code (Prentice Hall, 2004)
  • Kent Beck, Test-Driven Development: by Example (Addison-Wesly Professional, 2002)
  • Steve Freeman, Nat Pryce, Growing Objective-Oriented Software, Guide by Tests (Addison-Wesly Professional, 2009)
  • Gerard Meszarom, xUnit Test Patterns: Refactoring Test Code (Addison-Wesley, 2007)
  • Mark Seeman, Dependency Injection in .NET (Manning Publications, 2011)
  • Erich Gamma, Rchard Helm, Ralph Johnsonm John M. Vlissides, Design Patterns (Addison-Wesley, 1994)

Part 1 入門

CH1: 單元測試的基礎

本章中定義了優秀單元測試具有的特質,並且解說如何區分單元測試和集成測試。並說明了不使用框架進行集成測試的缺點,最後探討 TDD。

綱要

  • 定義一個單元測試
  • 對比單元測試與集成測試
  • 探索一個簡單的單元測試示例
  • 理解測試驅動的開發

書摘

  • 一個單元測試是一段程式碼(通常是一個方法),這段程式碼調用另一段程式碼,然後檢驗某些假設的正確性。如果這些假設是錯誤的,單元測試就失敗了。一個單元可以是一個方法或函數。
  • SUT 代表 System Under Test,也就是被測試的系統
  • 一個單元測試代表系統中的「功能單元」或者一個「用例」
  • 從調用系統的一個公共方法到產生一個測試可見的最終結果,期間這個系統發生的行為總稱為一個工作單元。
  • 一個最終結果可以是:公共方法的返回值、系統的狀態或行為有可見的變化、調用了一個不受測試的第三方系統,該系統不返回任何值,或者返回值都被忽略。
  • 一個單元測試的範圍可以小到一個方法,大到多個類別
  • 優秀單元測試應該是自動化,可重複執行的、能夠一鍵運行、速度很快、結果穩定、完全個離、容易發現什麼是期待得結果,進而定位問題所在
  • 如果一個測試要使用真實的系統時間,真實的檔案系統,或者一個真實的資料庫,那這個測試就進入了集成測試的領域
  • 集成測試可能帶來的另一個問題就是一次測試的東西太多了。
  • 集成測試是對一個工作單元進行測試,該測試對被測試的工作單元沒有完全的控制,並使用該單元的一個或多個真實依賴物。
  • 集成會使用真實的依賴物,而單元測試則把被測試單元與其依賴物隔離開。
  • Michael Feathers 把遺留程式碼定義爲沒有測試的程式碼,而作者認為可以透過三個問題去審視:
    1. 我能在幾分鐘跑完我寫過的所有單元測試嗎?
    2. 我能一鍵運行我寫過的所有單元測試嗎?
    3. 我能在幾分鐘內寫出一個基本測試嗎?
  • 一個簡單的單元測試範例
  • 重構意味者在不改變一段程式碼功能的前提下修改程式碼。
  • 成功進行 TDD 的三種核心技能
    1. 知道如何編寫優良的測試
    2. 在編碼前寫測試
    3. 良好的測試設計

CH2: 第一個單元測試

綱要

  • 探索 .NET 單元測試框架
  • 使用 NUnit 編寫第一個測試
  • 使用 NUmit 屬性
  • 理解一個工作單元的三種輸出類型

書摘

  • 不使用單元測試框架的測試通常有所受限:不是結構化的、不可重複、不能覆蓋程式碼所有重要的部分。
  • 使用單元測試框架並不能確保你編寫的單元測試可讀、可維護以及可靠。
  • 安裝 NUnit 最好的方式是使用 NuGet。
  • 在方案中添加一個新的類別專案,用來放置測試類別,並把項目命名為 <被測試專案的名稱>.UnitTests
  • NUnit 運行器至少需要兩個屬性才能知道要運行什麼
    • [TestFixture] 標識一個包含自動化測試的類別
    • [Test] 標識這個方法是一個需要調用的自動化測試
  • 被測試專案程式碼
  • 自動化測試專案程式碼
  • 一個單元測試通常主要包含三個行為:
    1. 準備(Arrange)物件,創建物件,進行必要的設置
    2. 操作(Act)物件
    3. 斷言(Assert)某件事情是預期的
  • Assert 類別是你的程式碼和 NUnit 框架之間的橋樑,用於聲明某個特定的假設應該成立。
  • 紅綠燈的概念在單元測試領域,特別是 TDD 中非常流行。他的思路是「紅-綠-重構」。先從失敗的測試開始,然後使測試通過,最後重構提高可讀和維護性。
  • NUnit 有一個功能叫做參數化測試(parametrized tests):
    1. [Test] 換成 [TestCase]
    2. 把 hardcode 的值替換成參數
    3. 把替換的直放在屬性中的括號中 [TestCase(param1, param2, ..)]
    4. 用一個比較通用的名稱重性命名這個測試方法
    5. 把這個測試方法是上,對每個需要合併的測試方法,用其測試值添加一個 [TestCase(...)]
    6. 移除其他測試,只保留有添加 [TestCase] 屬性的測試方法
  • 你可以在一個測試方法上添加多個 TestCase 屬性,如這段程式碼
  • NUnit 還有些特別的屬性,可以方便控制測試前後的設置和清理狀態的工作。那就是 [SetUp][TearDown]
  • 使用 [SetUp] 越多,測試程式碼的可讀性就越差。
  • 作者建議採用工廠方法初始化被測試到實例。
  • [TestFixtureSetUp][TestFixtureTearDown] 可以在一個特定的類別中所有測試運行前後進行一次狀態設置和清理。
  • 測試中的 [TearDown] 方式有意義的,那就是需要在測試之間重置一個靜態變數或單例的狀態。任何其他情況使用 [TearDown],都有可能是在做整合測試。
  • [ExpectedException] 可以用來檢查異常,將例外訊息做為參數。該屬性包含斷言,所以測試方法本身沒有使用 Assert,也不需要從被測試方法取得布林結果。值。這個屬性基本上是告訴測試運行氣把這個方法包在一個大的 try-catch 區塊裡,如果沒有例外捕捉到,就認為測試失敗。這種方法有一個很大的問題,就是你不知道哪一行程式碼拋出了這個例外。
  • 測試例外可以使用 Assert.Catch<T>(delegate) 這個 API,使用一個不帶參數的 Lambda 表達式,並在裡面呼叫預期會拋出異常的方法。如果 Lambda 之外的程式碼拋出例外,這個測試就會失敗。Assert.Catch 會返回 Lambda 內拋出的例外的實體,之後就可以針對這個實體提供的訊息做斷言。
  • 使用 StringAssert.Contains 做斷言會比 Assert.AreEqual 更容易維護。
  • 若是要忽略測試程式碼,可以在該方法是加一個 [Ignore] 屬性。並可以提供忽略的理由字串作為參數。
  • 可以使用 [Category] 為測試方法分類。
  • 基於狀態的測試(狀態驗證):通過檢查被測試系統及其協作方(依賴物)在被測試方法執行後行為的改變,判定被測試方法是否正常運作。如這個方法是無法通過獲得方法返回值的測試檢查他,只能透過如這樣的測試去檢查。
  • 若需要公開調用某個方法改變系統的狀態,測試方法名字應該以這個方法開頭。
  • 把測試方法名當作一個句子來讀
  • 如果沒有前置動作而有一個預期的返回值,可以用 ByDefault 命名,如 Sum_ByDrfault_ReturnsZero
  • 對於第二種或第三種工作單元結果(改變狀態或調用第三方系統),如果不虛藥進行前期配置,系統狀態以經改變或第三方調用已經完成,可以用 WhemCalledAlways 命名。如:Sum_WhenCalled_CallsTheLoggerSum_Always_CallsTheLogger
  • 測試方法的命名規則:[UnitOfWork]_[Scenario]_[ExpectedBehavior]

Part 2 核心技術

CH3: 使用存根破除依賴

本章中學會了如何使用介面和繼承,用存根去除依賴項。

綱要

  • 定義存根(stub)
  • 重構程式碼並使用存根
  • 克服程式碼的封裝問題
  • 探索使用存根的最佳實踐

書摘

  • 一個外部依賴項(external dependency)是系統中的一個物件,被測試程式碼與這個物件發生交互,但你不能控制這個物件。(常見的外部依賴項包括文件系統、執行緒、記憶體以及時間)
  • 一個存根(stub)是對系統中存在的一個依賴項(或協作者)的可控制的替代物。通過使用存根,你在測試程式碼時無須直接處理這個依賴項。
  • 模擬物件(mock)和存根(stub)很類似,但是你會對模擬物件進行斷言,而不會對存根進行斷言。
  • 一但依賴於檔案系統,你進行的測試就是整合測試,會帶來與整合測試相關的問題。
  • 抑制測試(test-inhibiting)設計的實質:程式碼對一個外部資源有某種相依關係,儘管程式碼本身的邏輯是對的,但是這種相依關係可能導致測試失敗。
  • 沒有一個物件導向的問題不能用增加一個間接層(a layer of indirection)解決,當然,除了間階層過多這個問題。
  • 重構(refactoring)是在不改變程式碼功能的前提下對程式碼修改。也就是說,程式碼在修改前後做的工作是完全相同的,既不多也不少,只是程式碼外觀看起來不一樣了。重構的例子有:重新命名一個方法,或者把一個長方法拆成幾個較短的方法。
  • 接縫(seam)是程式碼可以插入不同功能的地方,這些功能包括使用存根類,添加一個建構函數參數、添加一個可以設置的公共屬性、把一個方法改成可以重寫的虛擬方法、或者把一個委託外部化成一個參數或屬性以便從類別的外部賦值。程式碼設計的開放封閉原則(Open-Closed Principle)要求:類別的功能是開放的,允許對其擴展;而原始碼是封閉的,不可直接修改。遵循開閉原則,實現的程式碼中就會有接縫。
  • 請注意這個類別的獨特命名,這一點非常重要。這個類別不叫 StubExtensionManager 或者 MockExtensionManager,而是 FakeExtensionManager。在類別名稱中使用 fake 這個關鍵字,說明這個類別的物件類似於另一個物件,但是這個 fake 類別的物件季可能用做模擬物件(mock),也可能用作存根(stub)。如此就可以推遲決定這個替代物得物件到底是模擬物件還是存根,以後在不同的測試就得以重用。
  • 使用構造函數注入存根
  • 加入越來越多地建構函數(或越來越多地建構函數參數),會越來越困難,甚至還會降低程式碼的可讀性和可維護性
  • 創建一個特殊的類別,包含初始化一個類別所需的直。建構函數只有一個參數:這個特殊的類別。這樣的話,你只需要傳遞一個包含所有相關依賴項的物件。(這種方法也稱為參數物件重構(Parameter object Refactoring)。)
  • 使用控制反轉(Inversion of Control, IoC)容器。
  • 除非使用類似 IoC 容器的輔助框架來建立物件,使用建構函數參數來初始化物件會使測試程式碼變得笨拙。但是和其他依賴注入的方法相比,我還是願意使用建構函數注入,因為在 API 的可讀性和可理解性方面,建構函數注入帶來的影響是最小的。
  • 若是想讓這些依賴項目成為可選項目,可以使用獲取方法(Getter)和設置方法(Setter)的屬性。
  • 在單元測試中,你會經常面對困境:無法決定在何種情況下使用何種技術或設計方法。這是件好事。記得要總是質疑自己的假設,你也許能從困境和思考中得到新的啟發。
  • 若是在對一個物件進行操作之前才能得到其實例,而不是通過建構函數獲釋屬性得到。可以使用工廠類別去獲取該物件,並在測試方法透過設置方法對工廠類別設置要對被測試方法返回的物件。一但使用這個模式,你唯一要確保的是,要在你的工廠類別中加入一個接縫,使它們可以返回存根,而不是默認實作的類別。
  • 你可以用一個條件編譯參數控制接縫語句。
  • 可以在程式碼中返回存根的三種不同的層次深度:
    1. 在被測試類別中偽造一個成員:添加一個用作依賴項的建構函數參數。
    2. 在工廠類別中偽造一個成員:突過設置工廠類的屬性,讓工廠類返回你偽造的依賴項。
    3. 偽造工廠類別:把工廠類實力替換為返回偽造依賴項的偽工廠
  • 層次越深,控制能力就越大,但測試就越難理解,越難找到放置接縫的合適位置。
  • 間接曾越接近程式碼的表層,你越少需要修改依賴項。
  • 使用被測試類中一個局部的虛擬方法作為工廠方法。如此就可以透過繼承的方式編寫一個可測試的類別,就不用再修改原被測試類別。
  • 抽取和重寫(extract and override)是一種強大的技術,因為它使你無需進入更深層次即可替換依賴項,即可直接替換依賴項,實現是來快鋉乾敬,幾乎影響了你對物件導向的美好感覺,導致你編寫更少的介面、更多的虛擬函數。我喜歡把這種方式叫做「破解與重寫」(ex-crack and override),
  • 抽取和重寫非常適合用來模擬提供給被測試程式碼的輸入,但是如果用來驗證從被測試程式碼到依賴項的調用卻十分不便,隔離框架更適合做這樣的工作。
  • 如果要模擬返回值或者整個返回街口,抽取和重寫都很合適,但是要檢查物件之間的交互,這種方式就不太適合了。
  • 只有一種情況下作者不會使用這項技術,那就是程式碼明顯已具備了所需條件:有一個偽造的介面、或者已經有一個可以注入接縫的位置。
  • 物件拗項技術的存在是為了限制 API 的最終使用者(最終使用是使用你編寫的物件模型的程式設計師)的行為,使物件模型能得到最正確的使用,避免誤用。
  • 封裝外部依賴項目、不允許修改、使用私有構造函數或密封類別、使用不能重寫的非虛擬方法,所有這些都是過度保護鶚記得經典特徵。
  • 可測試物件導向設計(Testable Object-Oriented Design, TOOD)
  • 使用組建層級(assembly-level)的屬性 [InternalsVisibleTo],使所有 internal 的成員和方法對測試程式及可見。
  • 在方法上使用 [Conditional] 屬性,在編譯時,若該編譯標誌不存在,帶標記的方法又不會包含在這編譯版本中。
  • 在產品程式碼中使用條件編譯結構會降低程式碼的可讀性。

CH4: 使用模擬物件進行交互測試

了解如何測試第三種最終結果——調用第三方物件。被測試的物件可能不會返回任何結果,或者保存任何狀態,但是他有一套複雜的邏輯,需要正確的調用其他物件,而被調用的物件不受你的控制,或者不是被測試單元的一部分。之前掌握的方法在這裡都不適用。

綱要

  • 定義交互測試
  • 理解模擬物件
  • 區分偽物件、模擬物件、存根
  • 探索使用模擬物件的最佳實踐

書摘

  • 交互測試是對一個物件如何向其他物件發送消息(調用方法)的測試。如果一個特定的工作單元的罪中節果是掉用令一個物劍,就需要進行交互測試。
  • 可以把交互測試看作行為驅動測試(action-driven),是指測試一個物件採取的特定行為。
  • 請總是把交互測試最為最後的選擇,交互測試會讓很多事情變得更複雜。
  • 倫敦學派 TDD(the London scholl of TDD)則是基於設計目的,將存根和模擬物件引入軟體設計。
  • 模擬物件是系統中的偽物件,他可以驗證被測試物件是否按預期的方法調動了這個偽物件,因此導致單元測試通過或者失敗。通常每個測試最多有一個模擬物件。
  • 偽物件是通用的術語,可以描述一個存根或者模擬物件(手工或非手工編寫),因為存根和模擬物件看上去都很像真實物件。一個偽物件究竟是存根還是模擬物件取決於在當前測試的使用方式:如果這個為物件用來檢驗一個交互(對其進行斷言),他就是模擬物件,否則就是存根。
  • 使用存根時,對被測試類進行斷言。存根只是輔助測試運行。
  • 使用模擬物件時,被測試類與模擬物件進行通訊,模擬物件記錄所有通訊。測試使用模擬物件驗證是否通過測試。
  • 存根與模擬物件最根本的區別在於,存根不會導致測試失敗,而模擬物件可以。
  • 模擬物件比存根物件多做了一件事:它保存通訊的歷史紀錄,這些記錄之後用於預期(expetation)驗證。
  • 只有當你把偽類在測試中作為模擬物件使用時,他才會成為模擬物件。
  • 斷言不是直接寫在模擬物件內部的。否則會無法重用這個物件,且降低了可測試性和可維護性。
  • 如果第一個斷言失敗了,其他斷言還要繼續執行,這說明你需要把這個測試拆成幾個。或是可以建造一個參數類,用有正確屬性的實體物件作為預期物件ㄡ
  • 如果一個測試只測試一件事情,測試中應該最多只有一個模擬物件。所以的其他偽物件都是存根。
  • 過度指定(overspecification)試過多的指定測試中應該發生的事情的行為,而這些事情實際上對測試無關緊要。
  • 要避免使用調用鏈,除了可以建立一個虛擬方法提供最終需要的物件,另一個方法是在 API 外層建立特殊的封裝類,簡化 API 的使用和測試,此種模式稱為 Adapt Parameter。
  • 手工編寫模擬物件會有許多問題:
    1. 編寫花費了許多時間
    2. 可能會需要在手工偽實現裡寫許多標準程式碼。
    3. 難以在其他測試中重用模擬物件和存根程式碼。

CH5: 隔離(模擬)框架

綱要

  • 理解隔離框架
  • 使用 NSubstitute 建立存根和模擬物件
  • 探索存根和模擬物件的進階用例
  • 避免隔離框架使用中的常見錯誤

書摘

  • 隔離框架(isolation framework)即一個在運行時建立和設定偽物件的可重用類別庫。這些物件稱為動態存根(dynamic stub)和動態模擬對像(dynamic mock)
  • 透過 NSubstitute(簡稱 NSub)的使用,瞭解到他的 API 帶給測試的各種好處,進而理解如何使用框架能提高測試質量。
  • 一個隔離框架是一個可編程的 API,使用這套 API 建立偽物件比手工編寫容易得多、快得多、而且簡潔的多。
  • 隔離框架如果設計得當,可以把開發人員從編寫重複程式碼,進行斷言或者模擬物件交互中解放出來。如果設計極為精妙,隔離物件可以使測試持續用很多年,開發人員不需要為了一點小的產品程式碼改動而回頭修復測試程式碼。
  • 要理解隔離框架的價值,最好的方法莫過於提出手工編寫測試常見的一個問題,看看隔離框架如何解決這個問題。
  • 動態偽物件是在運行中時建立的任何存根或模擬物件,它的建立不需要手工編寫程式碼。
  • NSub 支援準備-執行-斷言**(arrange-act-assert)**模型。
  • NSub 有一個 Substitute 類別,用於在運行時生成偽物件。這個類別有一個 For(type) 方法,有泛型和非泛型兩種實作,是使用 NSub 在應用程序中引入偽物件的主要方法。
  • NSub 是一個受限框架,他最適合為介面建立偽物件。對於類別,Nsub 只能為非密封的類別建立偽物件,其中也只能偽造類別中的虛擬方法。
  • NSub 命名空間提供了一個擴展方法作為斷言,你可以使用 Received() 方法斷言在測試中調用了偽物件的某個方法。詢問偽物件的這個方法
    是否調用過,若沒有,這個測試應該失敗。
  • 透過 Returns() 擴展方法,可以指定偽物件指定方法的返回值。
  • 如果不需要知道返回值實際是什麼,可以使用參數匹配器(argument matcher) Arg.Any<Type>() 忽略具體參數值。
  • 如果要模擬例外事件,則可以使用 .When(Lambda()).Do(Lambda)
  • 參數匹配約束(argument-matching contraint)既可用在準備階段,也可以用在斷言階段。
  • 隔離框架使用的越多,測試程式碼可讀性就會越差。一個斷言裡出現了不只一個 Lambda 表達式,就該去質疑:使用手工偽物件產生的程式碼是不是會有更好的可讀性。
  • 要使用測試整個物件的方法,需要滿足:
    • 容易建立帶有預期屬性的物件
    • 需要測試目標物件的全部屬性
    • 完全知道每個屬性的確切值
    • 進行比較的兩個物件正確實現了 Equals() 方法。
  • 使用比較物件的方法,就不能使用參數匹配器,測試的健壯性就會比較差。
  • 盡量不使用物件比較,而是使用參數匹配器來測試少量屬性
  • 要測試事件相關活動,由於事件是雙向的,所以有兩個方向:測試監聽事件的一方、或是測試觸發事件的一方。
  • 要檢查一個物件是否註冊到另一個物件的一個事件,比較好的實現方式是:檢查監聽物件是否對發生的事情做出某種反應。
  • NSub 提供 Raise.Event<Action>() 方法去觸發事件。
  • 測試事件是觸發的簡單方式是,在測試方法內部使用一個匿名委託,手工註冊這個方法。這個委託只記錄這個事件是否觸發。
  • 選擇使用委託而不是 Lambda,是因為使用委託的程式碼可讀性比較好。
  • 儘管 Moq 目前是最多人使用的,但 Moq 提供的錯誤訊息不準確,API 裡 mock 這個詞也出現得過多。
  • 選擇使用一個框架,然後盡量堅持使用它。
  • 隔離框架的優點
    • 更容易驗證參數
    • 更容易驗證多次方法調用
    • 更容易建立偽物件
  • 隔離框架的陷阱
    • 測試程式碼不可讀
    • 驗證錯誤的東西
    • 一個測試有多個模擬物件
    • 過度指定測試
  • 要測試一個物件,比較好的辦法是測試當事件觸發時發生了一些有意義的事情。
  • 盡量避免使用模擬物件。如果超過 5% 的測試使用了模擬物件,你可能就過度指定了事情。
  • 若要避免過度指定測試,盡量使用非嚴格模擬物件,也盡量使用存根而非模擬物件,更要避免把存根作為模擬物件使用。不要驗證是否在測試中調用了一個存根物件的方法。

CH6: 隔離(模擬)框架

綱要

  • 使用受限框架和不受限框架
  • 理解基於探查器的不受限框架如何工作
  • 定義優秀隔離框架的價值

書摘

  • 隔離框架分兩類:受限(constrained)框架和不受限(unconstrained)框架
  • 有些東西是受限(constrained)框架無法偽造的,.NET 受限框架不能偽造靜態方法、非虛擬方法和非公共方法
  • 受限(constrained)框架和手工偽造物件是一樣的,但他是在運行時生成和編譯代碼,因此它們會受限於編譯器和中間語言(Intermediate Language, IL)的能力
  • 不受限(unconstrained)框架不在運行時生成和編譯從其他代碼繼承過來的代碼。所有 .NET 的不受限框架都是基於探查器(Profiler-based),使用一套叫做探查器API(Profiling API)的非託管 API。
  • 不受限框架可以為以前無法測試的代碼編寫單元測試,也可以偽造無法控制、而且極難協同測試的第三方系統。
  • 除了 .NET 框架裡的某些核心類型,不受限框架 Typemock 幾乎支持你能想到的任何偽實現。
  • 不受限框架 MS Fakes 的 API 主要允許你以自己的委託方法替換公共方法(靜態或非靜態),但他不直接支持非公共方法的偽實現
  • 優秀隔離框架的兩大價值:適應未來、可用性
  • 新的測試框架中支持兩大價值的一些功能:遞歸偽物件、默認忽略參數、泛偽造、偽造物件的非嚴格行為、非嚴格模擬物件
  • 隔離框架設計的反模式:概念混淆、錄製與重放、黏性行為、複雜語法
  • 概念混淆亦可稱為模擬過量(mock overdose),框架中不該總是使用 mock 這個詞。我們必須知道測試中有多少個模擬物件和存根物件
  • 為了避免概念混淆,可以再 API 中對 mock 和 stub 使用具體的詞、或是在 API 中無權不要使用 mock 和 stub,而是使用一個通用的詞,並在命名變數時,使用類似 mockXXX 和 stubXXX 以緩解可讀性的問題。
  • 錄製與重放(record-and-replay)風格極大降低了代碼的可讀性,明顯的標誌就是:毒測試的人需要在一個測試中多次前後尋找才能理解測試內容
  • 如果你的測試需要在每次產品代碼調用偽造方法時都提供一個「現在應該做什麼」的答案,那隔離框架可給行為添加預設的黏性(stickiness)。一但我們告訴一個方法以某種方式工作,這個方法會一直這樣工作,直到告訴他不再如此。

Part 3 測試代碼

CH7: 測試層次與組織

綱要

  • 在自動化每日建置中運行單元測試
  • 使用持續整合進行自動化建置
  • 在解決方案中組織測試
  • 探索測試類別的繼承模式

書摘

CH8: 優秀單元測試的支柱

綱要

  • 編寫可靠的測試
  • 編寫可維護的測試
  • 編寫可讀的測試
  • 探索單元測試命名規範

書摘

Part 4 設計和流程

CH9: 在組織中引入單元測試

綱要

  • 成為一個變革的倡導者
  • 自上而下還是自下而上地實施變革
  • 準備好回答關於單元測試的疑問

書摘

CH10: 遺留程式碼

綱要

  • 探討遺留程式碼的常見問題
  • 決定從哪裡開始測試
  • 介紹處理遺留代碼時可以使用的工具

書摘

CH11: 設計與可測試性

綱要

  • 從可測試性測試目標獲益
  • 衡量可測試性設計的利弊
  • 對難以測試的設計進行改進

書摘

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.