熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

診斷 Java 代碼: 設計“可測試的”應用程序

2022-06-13   來源: Java核心技術 

  在診斷 Java 代碼的這一部分中Eric Allen 暫停了對具體錯誤模式的討論轉而選擇討論關於設計易於甚至我們樂於測試的軟件的問題他概述了七條設計原則這些原則能大幅提高您編寫測試代碼的效率並因此提高結果代碼庫的健壯性請在討論論壇與作者和其它讀者共享您關於本文的心得
  謹以本文獻給周二攻擊的受害者向災難挑戰的英雄們和美國人民的鋼鐵意志
  當設計大型程序的時候您必須時刻留心不同設計選項對諸如性能和可擴展性這樣的特征的影響隨著軟件產品的日漸復雜及其無所不在的部署軟件的可測試性也成了更重要的考慮事項
  
  徹底測試代碼的重要性是顯然的花在編寫測試和測試代碼上的時間和精力給您帶來的回報是維護成本的大幅降低
  
  然而除非您很小心否則您花在測試代碼上的精力可能會首先達到花在編寫代碼上的精力的幾倍!我曾看到程序員們齊心協力地對他們的全部代碼進行單元測試結果花在上面的時間使大多數人都以沮喪而告終
  
  幸運的是沒有必要這樣在您設計軟件的時候應用一些基本原則編寫易於測試甚至使測試成為樂趣的代碼是可能的
  
  跟其它編碼原則一樣這些原則也不是不容置疑或不可改變的教條有時候打破這些規則也是必要的因此理解每條原則背後的動機和判斷何時這些動機不適用(或應讓位給更關心的問題)的能力是很重要的
  
  原則 到 GUI 視圖的外面去
  盡可能把代碼移到 GUI 視圖的外面然後各種 GUI 動作就能成了模型上的簡單方法調用為什麼您需要這樣做呢?
  
  對 GUI 測試者來說通過方法調用測試功能比間接地測試功能容易的多
  另一個好處是它使修改程序功能而不影響視圖變的更容易
  當然視圖中也可能存在錯誤在理想情況下對程序的測試將同時檢查模型和視圖(想更多了解測試視圖請參閱我關於 Liar View 錯誤模式的文章或 Jeffries 等人的 Extreme Programming Installed這兩個鏈接都在參考資料部分
  
  原則 使用類型進行錯誤檢查
  類型是您的朋友 — 盡可能多地用類型系統自動檢查錯誤
  
  類型能在程序運行之前自動捕捉程序中的錯誤沒有靜態類型檢查的話類型錯誤將作為破壞者逗留在您的程序中直到恰當的執行路徑碰巧把它揭露出來為止
  
  最大限度地發揮使用類型的長處是棘手的通常一組數據結構可以在一個抽象級別上一起使用或者被分出成為一個單一的更高抽象級別的一個新的相關數據類型
  
  事實上編程語言自身的歷史可以看成是可以編程的抽象級別的逐漸提高匯編語言提供了比特到整數和浮點數的抽象接下來是記錄和函數抽象然後又是諸如對象線程以及異常這樣的抽象
  
  在每一抽象級別上達到與更高級別抽象一致的功能是可能的但那實質上僅僅是耗費更多精力冒更多的錯誤風險
  
  在面向對象語言(其它現代語言也一樣)中一個程序員在設計抽象上有很大的靈活性在哪個抽象級別上設計程序就成了基於折衷的決定比如由抽象級別提供的更多的健壯性和由於不能在更低抽象級別上工作而帶來的表達性(有時是性能)的損失
  
  通常高級別抽象帶來的健壯性和簡單性的價值很少被其它考慮事項超過(要了解對這個問題的更多討論請參閱我關於 Impostor Type 錯誤模式的文章在參考資料部分有它的鏈接
  
  原則 使用調節器避免故障線路(fault line)
  我用故障線路來指獨立組件之間的接口獨立組件之間和組件與其相應子組件之間相比很少有交互這種故障線路的一個典型示例是 GUI 視圖和它的模型之間的接口其它示例包括在編譯器中處理的不同階段之間的接口或操作系統的內核和用戶界面之間的接口
  
  找出程序的故障線路然後用具有轉發功能的調節器快速訪問聚合組件
  
  沿著故障線路隔離測試每個組件通常更容易但如果每個組件暴露的對象有很多或者組件中您想測試的一些對象只有通過多個嵌套引用才能訪問那麼測試就會變的很乏味
  
  不用隔離測試而是擁有您在它上面調用您想測試的各種方法的單個調節器對象通常是有幫助的這個對象然後能把這些方法調用轉發到適當的地方
  
  沿著相同線路設計和自己的測試代碼串聯在一起的程序組件接口是有益的這將使您把注意力集中在使這些接口盡可能簡單上
  
  原則 方法小型簽名和缺省參數
  使用小型方法說明和重載帶缺省方法參數的方法將使您在測試中調用這些方法變的愉快的多否則在測試這些方法時您將不得不構造額外參數如果參數很大那麼將很快導致代碼膨脹更糟的是它會誘使您編寫比在其它情況下更少的測試
  
  原則 訪問器不應修改內存狀態
  請在您的測試中使用不修改內存狀態的訪問器來檢查對象狀態
  
  在某些方面測試和實驗室試驗相似它們都想證明特定假設有效如果特定檢查動作改變了該領域的狀態那麼要這樣做會變得困難的多
  
  與量子力學領域不同計算機進程的狀態可以不修改就被檢查使用這種原則對您有好處
  
  原則 用接口說明外部程序組件
  用接口說明外部程序組件使得我們可以容易地在測試案例中模擬這些組件
  
  這條原則能節省大量時間特別是當外部組件的實現還未完成時通常大多數基本組件都不能准時可用如果這些組件不在適當位置您就不能測試您自己的代碼的話那麼您就在朝災難走去您的客戶不會關心您只有兩個小時來集成遲到了兩周的組件他們知道的全部就是整套產品被延期了和這是違約的
  
  原則 優先編寫測試代碼
  優先編寫測試代碼這是標准的 XP 方法但卻總有一種忽視它的誘惑
  
  每次我屈服於這種誘惑時我都感到後悔假設您正努力生產正確的代碼那麼您 好象能從推遲編寫測試代碼中節省的時間其實只是一個幻想
  
  注意這不是說您應該一次性編寫全部測試代碼後再一次性全部實現編寫一些測試代碼實現它們再編寫一些測試代碼再實現它們等等是個更好的辦法設計以這種方式得以進展在實現階段捕捉錯誤並在下一組測試中改正它以這種方式編寫測試也更少會使人畏縮
  
  代碼比您需要的還多?
  只需一點點努力就可能容易地對任何程序進行徹底的測試當然不可避免存在這些原則不適用的情況於是看起來好像不可能對功能進行測試
  
  當出現這些情況時我盡力退一步地看這個問題我怎樣才可能測試這種代碼?相反地我問自己我怎樣才能以可測試方式編寫這些代碼呢?這種想法上的改變的結果經常是增加了大量 僅僅服務於簡化測試的功能
  
  什麼?別擔心出現這種情況完全正常
  
  就象很多現有的設計模式它們只是為了增加程序的可擴展性就往程序中添加很多類(例如 visitordecorator 等等)開發簡化測試的新模式是可以接受的實際上面向對象語言的很多特征都是為了簡化擴展而包含進去的為什麼語言的未來版本(或全新的語言)不應包含簡化測試的特征
  
  對 Java 語言來說這已經開始人們計劃在未來版本中包含很多更強大的類型系統斷言(assertion)等等就象面向對象的語言已經增加了我們重用和擴展現有代碼的程度將來面向測試的設計和特征將幫助我們增強新老代碼的健壯性
  
  參考資料
  
  參加本文的討論論壇
  
  
  DePaul 大學的軟件工程系在檢測 Java 空指針異常的自動化法則方面做了一些工作
  
  
  JUnit 主頁提供討論程序測試方法的很多有趣文章的鏈接並提供 JUnit 的最新版本
  
  
  如果您正用 VisualAge for Java 開發代碼請看看這篇文章 VisualAge for Java 中的調試和單元測試
  
  
  查閱 iContract 一個方便您往 Java 代碼中添加斷言的工具
  
  
  Roy Miller 和 Chris Collins 提供的文章XP distilled(developerWorks 月)說明了極端編程方法如何為您的 Java 工程帶來更大的成功
  
  
  查閱 Ex 上的官方的 XP 編程規則
  
  
  想了解如何測試視圖的一些觀點看看 Eric Allen 關於 Liar View 錯誤模式的文章(developerWorks 月)
  
  
  想更多了解測試視圖的觀點JeffriesAnderson 和 Hendrickson 的 Extreme Programming Installed(AddisonWesley 年)會很有用
  
  
  想了解為什麼使用更高級別的抽象是更有益的(即使它只是在逐步走向前台)請參閱 Eric Allen 關於 Impostor Type 錯誤模式的文章(developerWorks 月)
  
  
  在 developerWorks Java 技術專區上查找更多的 Java 參考資料
  
  
  關於作者
  Eric Allen 從 Cornell 大學獲得計算機科學及數學的學士學位並且是 Rice 大學 Java 編程語言小組的博士候選人在回 Rice 完成學位前Eric 是 CycorpInc 的 Java 開發者帶頭人他還在 Javaworld 主持Java 初學者討論論壇他的研究包括在源程序和字節碼級別上 Java 語言的語義模型和靜態分析工具開發Eric 還幫助開發 Rice 的 NextGen 編程語言編譯器NextGen 是一個支持泛運行時類型的 Java 擴展可通過 eallen@csriceedu 與 Eric 聯系
  

From:http://tw.wingwit.com/Article/program/Java/hx/201311/25902.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.