前言
在上海成立的“測試俱樂部”打算編寫一個測試雜志。我這為了這份雜志,并且為了將多年的經驗進行總結,打算編寫一系列的短文來闡述“測試分析與設計模式”這個題目。
這個題目主要關于在設計內進行的“白盒測試”。 如何通過測試的手段盡量多的,盡量早的在設計中發現潛在的問題,修改,彌補設計上的漏洞,從而從根本上提高軟件開發產物的質量。
基于接觸到的中國國內軟件測試黑盒為主的現狀,個人感覺把自己的白盒測試方面的經驗貢獻出來還是有些價值的。
但是如果泛泛而談白盒測試很難與實際的實踐結合起來,并且一般很難認識到白盒測試在設計驗證中的作用。這里要尋找一個與廣大軟件設計聯系的切入點。即能夠用來闡述方法,又能夠被利用到設計實踐中去。 設計模式是一個比較好的靶子。 不管是否有意識的運用,在軟件設計中,設計模式是非常普遍的。 而每種模式適用于特定的情景和問題。其像一把雙刃劍,在帶來解決問題的好處以外還帶來了潛在的風險。 設計中的測試分析就是對此楊長避短。
設計模式在運用時,粒度和抽象度取決于設計者要解決的問題和所處的設計環節。本系列文章不具體討論特定的設計模式適合何種環境和問題。事實上,很好的,很合適的設計模式也會因為團隊能力的不足而引起問題;反之,有時看上去愚蠢的,不合適的設計模式運用也并非無法解決設計問題,或許僅僅是麻煩一些而已。本系列是從測試分析的觀點角度來著重分析在對設計模型和代碼進行靜態分析或者發現測試需求時,每種設計模式所可能對應的薄弱點。
設計模式是軟件設計人員長期經驗的積累。某個設計模式可能對于解決某類設計問題特別合適。 但是“沒有銀彈”。所以任何設計模式不能完美的完全解決現實設計中的所有問題。特別是當依據設計模式把功能設計進行映射時,或者說當把具體功能通過設計模式進行具體的設計落實時,會有一些特別需要謹慎的地方,容易出錯的地方。 而測試分析,特別是針對設計的白盒測試分析,就應該根據這些容易出錯的地方去考慮各種設計中可能未考慮到的情況。
在現實軟件設計中,設計模式并非決定軟件的設計和實現的唯一因素。 一般來說軟件需求,設計模式和軟件所在的軟/硬件平臺所支持的軟件技術三者結合起來才決定了軟件的設計和實現究竟會是什么樣子。
分析視角
對所謂“容易出錯的地方”,“謹慎”的地方的描述可以有多種角度:
角度一:從ISO 9126的質量屬性角度:功能,可靠性,可用性,性能,可維護性 (Functionality, Reliability, Usability , Performance/Efficiency, Supportable/Maintainability, Portability)
角度二:涉及到某種特定的實現方式或者說語言,操作系統等等情況時,其可能的弱點
角度三:設計/代碼中的錯誤模型:(某種類型的錯誤由于設計模式對實現思路的劃分而特別集中在某些層次上,比如MVC中,對客戶輸入的合法性驗證可能是集中于V和M中。 即M是否提供了合法性驗證的方法,而V是否調用了驗證)
正向設計:
上層語義要求(即對功能需求的理解)
邏輯算法
下層語義作用/副作用
功能API (子模塊,其他模塊/子系統)
軟件問題API(并發問題--進程/線程,信號量,哈希表,窗口系統,內存管理)
異常處理:
數據范圍,長度,內容
錯誤返回/異常/信號/中斷
錯誤現場保護和恢復
Timeout
Overflow
在真正開始討論各個設計模式的問題之前,再次明確這里所謂“測試活動“的基本思路:
1. 任何期望,需求,要求達到的東西,要求遵守的規則等等都可以被表述為“測試需求“
2. 根據測試需求逐條在設計等等模型中推理其是否滿足就是“測試執行“的過程。
整個設計內測試或者說靜態測試過程就是不斷根據需求,架構等等上游模型,“發現測試需求”,然后通過邏輯推理等過程進行“執行”的過程。 這個過程里軟件是在測試人員腦海里“運行”的。 而此“運行”的基礎就是邏輯推理。
設計模式一: 抽象工廠( Abstract Factory)
抽象工廠是一種創建對象的方式。 其特性有二:
一.提供創建特定類的方法--通過抽象工廠類來創建特定的類。
二.實際的創建特定實現的類又通過特定的類工廠來進行。
從另外角度來說,抽象工廠允許進行2個不同緯度的抽象。 比如對于一類功能進行一個抽象緯度。而各類功能的不同的實現依賴又是另外一個緯度。 舉例來說同樣的“文本編輯”框,可以是一個類;但是其在Linux中和windows中的實現是不同的,所以第一個緯度是功能,第二個緯度是操作系統。 通過抽象工廠類,使用者可以創建一類功能的不同實現。
質量特性視角
從功能角度看,抽象工廠這種設計模式主要用來作對象的創建。 所以一般對功能的屬性沒有特別大影響。
抽象工廠模式在易用性上是提供了比較好的優勢的。
如果單純的運用該模式,只要不涉及到過于頻繁的創建/釋放動作,一般來說對系統性能也不會有特別大的影響。避免在應用抽象工廠模式中附加自己實現的動態綁定,基本可以比較好的確保代碼的性能。
從穩定性角度來講,抽象工廠模式帶來的風險與創建動作帶來的風險基本上是一致的, 即需要確認對象創建是否成功。當程序中對動態創建的對象進行足夠的合法性檢查時,該模式不會帶來更多額外的穩定性風險。
抽象工廠模式對于可維護性方面提供了2個緯度中一個緯度的可擴展性。但是直接在抽象工廠中定義的緯度的擴展性將會受到很大限制。 所以在確定抽象工廠類定義的緯度時,應該仔細考慮是否有比較大的擴展可能性--> 設計內的測試的分析對于這點,應該從過往的項目經驗出發;從客戶需求的歷史出發;從該緯度本身的“自然特性”出發提出可能的擴展點。(這里列出的擴展點就是測試需求)對這些擴展點發生的可能性進行評估和討論(而這樣的評估和討論就是測試執行)。 注意這里明確的提出可能的擴展點,以及對這樣的擴展點進行討論,正是測試活動之一。 所以必須對擴展點,以及其相關討論,結論進行記錄。簡單講,當認為不發生這種擴展的可能性很大時,對應測試項就是Pass;否則就是fail.