謬論的產生是由于缺乏直接的經驗。在缺乏信息的情況下,我們根據自己的想法形成了一些信念,并且會抱著懷疑的態度去看待我們所不知道的事情。在軟件開發領域,荒謬的想法將會給接近客觀真實的問題帶來困難,因此把預算和時間推到了風險上。
在我作為質量保證經理的時候,我從大量的軟件開發實踐中獲得了經驗,這種經驗包括迭代開發和稱作“瀑布式”的方法。前者模型通常會被認為比后者的方法更加現代。但是這往往是一個荒謬的想法:兩種方法都是產生于60年代。另外一個荒謬的想法是認為瀑布方法盛行于70年代。被譽為瀑布方法之父的Winston Royce認為這實際上是一種誤解。他建議單向的瀑布方法只是為了維護項目而存在的。Royce建議在第一次開發軟件應用程序的時候一個迭代要“執行兩次”。
從這種誤解開始,軟件開發領域產生了很多荒謬的言論。這篇文章將會質疑和揭穿一些廣泛流傳的關于迭代開發和迭代測試通常的一些荒謬的言論。包括迭代開發原則是如何解決這些通常的誤解的,并會把你帶到測試方法的真正道路上,這種方法將會減輕和避免很多軟件開發過程中的缺陷,其中有很多是被我們堅信的“謬論”。
謬論:在多數的軟件開發項目中,我們帶著拋棄這個代碼的想法,很快的編寫一個原型應用程序,用來降低風險和證明概念的正確性。
事實:這個方法沒有任何問題。但是,由于時間的壓力或者是結果的獎勵,我們并沒有拋棄這個代碼。事實就是:我們的原型實際上就是早期代碼。那個代碼就成為了我們新的應用程序的基礎和框架。然而,由于它是在假設會被拋棄的情況下建立的,它會迂回于需求評審,設計評審,代碼評審和單元測試之間。我們下一代的應用程序是建立在不確定的基礎之上的。
在迭代開發周期中,持續的驗證是一個好的方法,在每一個迭代開發早期的原型是被鼓勵的。但是任何的代碼在提交到產品前,都需要遵照最佳實踐,來保證它的穩定性和可維護性。一種鼓勵在項目最開始做正確軟件開發實踐的方法是使用初始代碼來計劃,檢驗和呈現你打算在軟件開發階段全程使用的過程。作為迭代測試方法的一部分,你可以使用早期代碼周期來測試你產品的概念,同時可以清除開發過程中的小故障。
謬論:在開發周期中過早的開始測試活動會增加產品交付的時間,降低產品的特性。
事實:測試在開發周期中不是耗時的活動。診斷并修正錯誤才是耗時的工作,是開發過程中的瓶頸。
測試不是導致我們產品擱淺的障礙——相反它是避免我們撞上巖石的燈塔。無論我們是否尋找錯誤,它都存在于產品中。迭代測試會幫助你接近它們產生的地點。迭代測試最小化了糾正錯誤的花費。
謬論:如果你沒有完成的產品那么你就不能做測試。
事實:迭代測試并不被限制必須測試代碼。
你的小組生產出來的每一個產品都可以根據可交付性的成功標準進行驗證。同樣的,你用來生產可交付使用產品的每一個過程或者程序都可以用你的成功的質量標準來確認。這包括產品概念,體系架構,開發框架,設計,方法和你遵循的開發程序。
你可以從這個局部列表中看到,多數的條目沒有包括代碼。因此,當你在等待有可交付使用代碼時,你已經錯過了維護質量和降低風險的機會。我不同意這個廣泛接受的觀念:“你不能對產品進行質量測試”。你可以這么做,只要你開始的足夠早。
謬論:如果在每一個開發部分都有一名開發人員(或者一個單獨的資源),那么你的工作將會更加有效率。在這個簡單的論點中,如果你擁有30名開發人員,那么2人一隊進行開發,你可以同時開發15個部分。如果你只給一個部分分配一名開發人員,那么你可以同時開發30個部分。這樣會使你的產品完成度更高。
事實:一個部分只用一名開發人員完成有很大的風險:沒有第二個人可以維護和理解這個部分的內容。這個策略產生了瓶頸和延遲。缺點,增加的需求或者修改會全部壓在這個開發人員身上。為了按時完成工作,你的開發人員不得不為延長的產品周期而付出在周末加班的代價,因為他是這個部分唯一可以繼續新特性開發和修正錯誤的人員?,F在你的整個項目時間表都由這個英雄般的“單個開發人員” 1 負責。一旦這個人離開了小組,去度假或者出現一些不可控的情況,那么你的時間表將延期。由于你選擇了這種執行和管理的開發策略,你現在不能對你的小組作出調整。
成對的開發,測試,代碼評審和設計評審聽起來更加有實際效果,它不但能增加產品的質量,還可以訓練其他部分的人員,它能夠增加你資源共享和維護項目代碼的能力。一隊中的兩個人員不必要都是這個領域的專家。他們只要擁有可以消除先前討論過的瓶頸問題的能力就可以了。
此外,把開發小組分成合理的更小的獨立小組,能夠使得擁有不同技術能力的開發人員在不同的方面更加有效的工作。一個小組分配多個人員,就可以避免把不同的任務分配給一個特定的開發人員。當你擁有多個資源可以分配的時侯,把一個任務分配給單個的開發人員會產生錯誤的依靠性。類似于銀行的多個出納員服務一條等待的客戶隊伍,當開發人員完成一個任務準備進入下一個任務的時候他們的效率會有所改進。
謬論:編寫代碼是開發人員的主要任務。
事實:在開發小組中每個人員的主要任務是生產符合客戶需要的產品。這就意味著當你做需求評審活動時,開發人員的主要工作就是“需求的評審”。當你做設計活動時,開發人員的主要任務就是建立和評審設計文檔。當你做代碼活動時,開發人員的主要任務就是產生沒有漏洞并且滿足客戶需求的代碼。當你做文檔評審活動時,開發人員的主要任務就是確保用戶的輔助原料和錯誤信息能夠使得客戶的知識曲線變得平緩。當你做安裝和設置工作的時候,開發人員的主要工作就是確??蛻艨梢院茌p松的設定和配置你的產品,這樣他們就可以盡可能高效的完成他們“真正的”工作。越是需要更大的努力來使用軟件完成任務,客戶的投資回報率就會越低,應用程序失敗的機率就會越高。
謬論:軟件開發和測試的需求需要很穩定并且盡早的定義好,這樣才最有效率。
事實:如果我們最終的目標是“有效率的軟件開發和測試”,那么穩定和定義良好的需求在最開始是必須的。但是我們實際的目標是生產一個客戶承認的產品。我們大部分人都承認我們往往不知道什么才滿足客戶需求的。因為在現今的市場情況下,需求是經常變化的,例如新的產品和選擇,我們經常要在被介紹新概念和信息之后改變我們的主意。如果你承認上面的情況,那么一個主要的原因就是為什么我們不能有效地保證需求的穩定性。在開發過程中頻繁的和產品交互會不斷暴露客戶的需求,使得我們變更我們的過程來更好的達到客戶的變化需求和價值。
謬論:當代碼設計的時間超過了時間表的計劃,降低測試的時間可以幫助我們重新回到時間表的計劃上。
事實:一般情況代碼設計的延誤是由于未預料到的困難或者沒有按照最開始的設計工作。當我們發現我們低估了項目的復雜性的時候,縮短測試時間是一個糟糕的決定。相反,我們應該保證測試的執行,因為測試的結果是建立在我們低估代碼設計的情況上的,測試的效果或許也會被低估。因此我們需要定制更多的測試時間來更正開始的判斷,而不是減少測試時間。
迭代測試增加了測試時間但是并沒有延誤整個的時間進度,因為在每一個迭代過程中測試過程都是提前開始的。同樣,產品的質量決定了需要測試的數量——而不是由時間決定的。例如,如果產品是可靠的,在很多領域都沒有發現缺陷,并且測試進行的十分順利,那么你可以在保證測試數量和測試覆蓋率的前提下降低測試的時間。如果產品不夠穩定,發現了很多缺陷,那么你需要增加測試的周期直到達到質量標準。請記住,測試并不是項目最耗時的工作。
謬論:找到并修正所有的缺陷將會建立一個高質量的產品。
事實:近來的研究顯示,只有10%軟件開發活動,例如建立客戶需求特性,能夠實際增加客戶的價值。開發過程中加入一定比例的特性能夠增加產品在市場中的競爭力,但是它們往往不是客戶要求或者期望的。查找和修正這些缺陷不會增加客戶的價值,因為客戶可能永遠也不會遇到這類的錯誤。
從另一個角度講,迭代測試實際上會減少缺陷的數量和客戶等待的時間,當然這是基于客戶價值考慮的。在迭代過程中引入客戶意見,迭代測試壓縮對客戶的交付周期,從而最大化應用程序對于這個客戶的價值。
謬論:不斷的回歸測試每一件我們更改的代碼是十分冗余和費時的工作,只有在理想化的世界中才會這么做。
事實:回歸測試并不意味著“每次測試每件事”。
迭代回歸測試的意思是測試每個階段中敏感的部分。它也意味著基于改動效果,產品歷史和早期測試結果而更改我們的測試覆蓋率。
如果你的回歸測試是自動執行的,那么你可以在同時運行所有測試。如果不是,那么請選擇你想要完成測試的部分進行測試。例如,你可以在“驗收”產品之前之前運行一個“完整的回歸套件”或者“一系列驗收測試”f。由于每一個回歸過程都不是必須相同的,測試不需要每一次都相同。把精力集中在特性和測試上面對于即將到來的交付階段是十分有意義的。例如,如果你使用第三方的組件,比如一個承包商或者開源的產品,完整的回歸套件將會把焦點集中在外部和內部組件的集合點上。如果在你初始化第三方模塊完整回歸測試時,發現了缺陷或者回歸,那么你可以選擇添加基于早期結果的額外測試來改變你的回歸套件。
換句話說,如果你在你的控制之下在整個產品開發中進行一系列的缺陷修復工作,那么完整的回歸套件應該被完全聚焦并構建在你的端到端,高概括的客戶用例上。如果更改被限制在一個領域,并且產品擁有一個穩定的質量追蹤記錄,那么你可以把精力全部集中在這個回歸套件中。同樣,在最后階段,你或許需要一個非常小的能夠覆蓋介質安裝的完整回歸套件,但并不是深層次的或者端到端的測試。完整或者驗收回歸套件的重點依賴于在前一個周期測試了什么,產品的一般穩定性和下一個迭代的重點。
謬論:這不是一個缺陷——特性隨著設計而出現。
事實:過多的解釋為什么產品會做它現在正在做的事情是一個普遍的陷阱。有時候我們知道的太多了。當缺陷被修復和評審的時候,我們經常為缺陷自圓其說。有時候我們把缺陷標志成為“伴隨設計更正”或者“不計劃修復”,因為應用程序實際上是伴隨著設計工作的,更改設計將是過于昂貴和具有風險的。同樣的,我們解釋了很多關于“它是一個外部組件”或者“它是一個鐘表或者汽笛”的可用性。我們的窗口小部件或者 UI 控件將會受到限制?;蛘呶覀兏嬖V我們自己“一旦用戶知道要這么做,他們將會很好”。
總而言之:我們了解了代碼的輸入和輸出,以及他們為什么這么工作。在這個部件層次上,我們做了非常合理和明智的決定。但是我們缺少對整個客戶經驗的整體觀。我們沒有給我們編碼平衡和工作區帶來最終效果增值。我們的主要聚焦點是使重要的代碼按時完成。通過聚焦于個別的特性或者組件,我們不經意的做了一些代碼的決定,這對產品的全面流程和可用性產生了消極的影響。畢竟,最大限度影響客戶效率的是可用性。而驅使用戶放棄一定數量功能的也是可用性。
超過上面的細節層次提升我們對于項目的見解,會允許我們以客戶期待的視角看待我們的產品——通過全局的層面,而不是單個的組件。這種提高后的視角幫助我們忽略了對于產品為什么這么工作的所有原因的探究??蛻舨粫P心給定的設計是否會加快代碼的設計。對于客戶來說用戶界面是否與你特定開發任務外的組件X的API沖突與他們無關。他們只關心這個產品在他們完成自己的目標時是否會協助或者阻礙他們的工作。
表1:舉例說明當我們測試應用程序的時候我們以客戶視角所提倡的一些做法。
當我們遇到這種情形時…… | ……我們應該…… |
---|---|
我們已經知道這是不正確的 | 分清什么是我們必須在交付使用之前確認的,以及什么是可以在交付之后再去確認的。分清楚所有者以及最終期限。 |
出于未來的考慮它在我們的列表中(沒有時間表日期)。 | 認識到它是否擁有一個“未來考慮”標簽(或者類似的東西),它不是真實的。和技術支持,市場顧問以及客戶一起工作,舉例說明缺陷或者特性的重要性。一旦團隊確定了客戶的價值,那么就可以確定一個交付使用時間和擁有者。 |
它是我們部門之外的人員的代碼。 | 建立一個SWAT小組,除了本部門人員外還包括“外部部門”的員工。確定一個交付期限以及兌現的所有者。 |
客戶或者駕駛員的錯誤。 | 學習文檔或者用法流程??蛻翦e誤經常是由于一些不清晰和不直覺的步驟產生的。明確的識別需要發生的改變,給它定義時間表,并且設立一個所有者。 |
按照計劃設計。 | 在工作視圖中需要一個完整的設計評審。弄清楚客戶或者角色從開始到結束是如何演出的。 |
這么做是由于XXX。 | 認識到如果XXX不是“因為客戶需要這么做”,那么XXX就是不相關的。把這個原因從討論中去除,并把它移到下一個要點。 |
謬論:一個測試人員的唯一任務就是找到程序缺陷。
事實:關于測試人員的作用的這個觀點是非常有局限性的,并且對于客戶沒有增加價值。測試人員都是被測試系統,應用軟件或產品的專家。不象負責一個特殊功能或組件的開發人員,測試人員懂得系統作為一個整體是如何工作的來達到客戶的目標。測試人員懂得由產品增加的價值,關于產品效率的環境的影響,以及從產品得到最多輸出的最好方法。
通過這個產品知識擴展了我們測試人員的價值和作用。擴展測試人員的作用(諸如技巧,技術,指導方針,以及為使用而進行的最佳練習)最終減少了客戶所有權的成本和增加了測試人員的商業價值。
謬論:我們沒有足夠的資源和時間來全面測試產品。
事實:你不需要全面測試產品——你需要充分測試產品來減少一個客戶將被消極地影響的風險。
變化市場的事實通常要求在給定的時間框架中詳盡地測試一個產品,但事實上是不可能的。這就是我們需要測試的一個實用方法的原因。關注于你的客戶的商業過程來確定你的測試優先級。聯合系統的內部客戶來測試你的產品。當提供真實世界可用性的反饋時,這些步驟增加了你的測試資源。同時你也可以在一個外部客戶實驗室中來做你的系統測試,來增長你的真實世界環境的經驗而不用增加你的維護或系統管理活動。
謬論:測試應當發生在一個被控制的環境中。
事實:測試環境越象最終產品環境,測試越可靠。如果客戶環境被嚴格控制,那么你可以在一個被控制的環境中做你所有的測試。但是如果最終產品環境沒有被控制,那么你在一個被控制的環境中做你測試的100%的工作將會使你錯過一些重要的情況。
盡管難以預測的事件和不同的環境難以效仿,但它們是十分常見的,因此也是值得期待的。在我們當前的全球市場能夠中,你的應用軟件將被用于靈活的,分布的,和多變的情況是十分可能的。在迭代測試中,我們因此根據處于不同環境中的客戶來同時確定商業使用模型檢查和系統測試活動的時間進度。早期的商業使用檢查確定目標客戶市場的差異性,優先于編碼。在客戶現場進行系統測試是在真實世界中運用了我們的產品。盡管產品的這些“預發布”版本仍然在我們開發人員的手中,并運行于我們的工作站上,但它們已經在客戶真實世界的辦公室(或實驗室)的環境和應用軟件中被測試。盡管這個策略不能覆蓋每一個可能性,但它承認不可預知性的存在。
謬論:所有的客戶有著同等的重要性。
事實:一些客戶要比其他客戶更加重要,這是基于一個特殊發布的目標。例如,如果一月發布的發布定義特性是將傳統MyWidget數據轉變為MyPalmPilot的特性,那么我們的用戶使用MyWidget和MyPalmPilot的反應對于這個特殊的發布來說,要比其他客戶的輸入更加重要。
所有我們的客戶當然都是重要的。但是迭代測試的目標是關注于這個特殊迭代法的最重要特性。如果我們正在將特性XYZ輸送到這個迭代法中,我們需要來自于熟悉優先的XYZ功能的使用者的專家對XYZ的評價。就象我們歡迎其它反饋一樣,諸如新使用者的印象,XYZ特性的優先考慮。在開發的這個階段,剛剛接觸市場的使用者不能幫助我們設計“正確的XYZ特性”。
謬論:如果我們正在尋找很多程序缺陷,我們正在做重要的測試。
事實:找到很多程序缺陷的唯一好處就是告訴我們產品存在很多程序缺陷。它沒有告訴我們測試覆蓋的質量,程序缺陷的嚴重性,或是客戶將在實際中碰到它們的頻率。同樣它也沒有告訴我們遺留下多少程序缺陷。
停止找到程序缺陷的唯一確定方法就是停止測試。它看起來是荒謬的,但這個想法是有價值的。這個難題的癥結在于指出產品的什么特性確實需要研究。我已經提到產品中的許多工作流實際沒有被使用——并且如果它們沒有被使用,它們就不需要被研究。直接在你的測試計劃中合并客戶使用知識以及缺點篩余機制提高了你預測客戶影響和與缺點相關的風險概率。在你的測試計劃解決中合并基于風險和客戶分析將產生一個更加實際和實用的測試計劃。一旦你對你的測試計劃有信心,你可以在你已經執行計劃之后停止測試。
你如何建立那種信心?開始你的測試計劃時要確定你需要測試的所有區域。讓客戶檢查和評價商業過程并使用實例以便你懂得每一個被提議的測試實例的頻率和重要性。要特別注意檢查測試漏洞。對每一個迭代要持續更新和檢查你的測試計劃和測試實例。你的目標是找到什么沒有被覆蓋到。做到這個的一種方法是通過軟件區域和測試種類來映射程序缺陷計數。如果一個軟件區域沒有被記錄缺點,它可能意味著這個區域是十分有效的或者它還沒有被測試??慈毕菸募臅r間戳。如果最后的缺陷是去年公布的,可能它暫時不用被測試。找到錯過的程序錯誤的模式是檢查測試覆蓋的一個重要技術。
謬論:完全的測試意味著測試 100% 的需求。
事實:測試需求是重要的,但是不是充分的。你還需要測試那些遺漏的事情。有什么重要需求的沒有被列出?
找到沒有被列出的是一個有趣的挑戰。 迭代測試很早就使客戶客戶參與進來??蛻舳盟麄兊臉I務如何進行和他們如何工作。他們可以告訴你你的應用軟件中錯過了什么,并且提出什么妨礙了他們需要完成的任務。
謬論:它是一個間歇的程序錯誤。
事實:不存在間歇的程序錯誤。問題是一直存在的——你只是沒有指出正確的條件來復制它。提供可用的工具來持續監控執行,應用軟件降級開始的自動校準,以及在降級的時候自動發出適當的數據(優先于應用軟件實際崩潰)減少內部故障診斷時間和客戶停工時間。迭代測試和迭代可用性活動都可以減少沒有被發現的程序錯誤對商業的影響。
更加實用和好用的診斷程序增加了你的產品的客戶價值。當你的產品開始升級時,通過前攝的監控環境,你可以減少分析時間甚至可以避免由于開始各種自動更正校準和工作區的例行程序而導致的停工。自治服務例行程序的這些類型增加了你的產品的可靠性,耐久性,和運行持續時間,甚至如果程序缺陷復制品的條件是未知的。
在某種意義上,自治的恢復例行程序提供了一個標準的持續的技術支持。環境記錄和處理跟蹤信息被自動收集并被發送,以用于更進一步缺點分析的開發,同時也提供了關于你的產品是如何被實際使用的重要數據。
如果我們承認程序缺陷是不可避免的,我們同樣需要認識到適當有用的例行程序的重要性。這些自診斷和自行監控功能在增加客戶價值和滿意度中是有效的,因為它們減少了客戶受程序缺陷消極影響的風險。然而即使這些例行程序增加了客戶價值,只有少數幾個開發周期被用于將這些過程歸位。
謬論:產品應當在壓力下被測試以驗證性能、可伸縮性和耐久性。
事實:上面是正確的。但它的反面也是正確的。使一個應用軟件保持在空閑,或長期處于暫停的狀態來仿效客戶去吃午飯或使應用軟件在周末暫停,并經常暴露一些問題。
我推薦在你的功能測試方法中包括睡覺,暫停,中止,中斷和睡眠狀態恢復。仿效一個地理分布式工作環境,當你的應用軟件處于中止或暫停狀態,而其中的共享工件和數據庫正在變化(正如同事們在其他人的業余時間在一個偏僻的地點工作)。測試當使用者“喚醒它”時發生了什么,這與他們被掛起的環境是不同的。然而更好的是將你的產品放到一個真實的客戶環境中并運行仿效上面的一些場景的系統測試。
謬論:客戶總是正確的。
事實:可能他不是一個正確的客戶。你不可能使用一個發布來使每一個人都滿意。因此,要在你的發布定義特性設置中有選擇性。瞄準一個特殊的,高度概括的測試場作為用戶的一種類型目標。然后對于下一個發布或迭代,選擇一個不同的人群。你將更有效地測試;當你的產品成熟的時候,你將通過在不同階段中增加滿意的客戶來增加你的客戶基礎。
事實:在腦海中客觀的看待自動化,并考慮 ROI。測試環境越象最終產品環境,測試的可靠性越高。如果客戶的產品是100%自動化的,那么自動化!自動化!自動化!如果你的產品不打算在客戶環境中實現自動化,那么你需要將自動化的,特殊化的,探查的以及客戶場景的測試進行合并。
它同時對于擴展你的自動化定義有所幫助。自動化測試實例可以重復測試你已經手工測試過的區域。但是那不能增加你的測試覆蓋或你對使用者對于應用軟件是如何反應的理解。相反,創建自動化實際上允許你投入更多的精力在創造性的手工測試上。使事情自動化是你經常需要做的并且那將使你花費很長的時間來完成,象:
為了得到更多關于增加你的對自動化投資回報的信息,訪問http://www-128.ibm.com/developerworks/rational/library/may05/rose/。
謬論:迭代開發行不通。
事實:它是人類對于未知和未嘗試的領域懷疑的天然屬性。在迭代開發經驗中,每一個成功階段的好處逐漸增加。因此,迭代方法的所有好處是只有在開發周期的末尾才被重視。對于第一個吃螃蟹的人來說,那個推遲的滿意可以真正地成為信念的行為。我們沒有使用方法的經驗,并且所以我們不太信任即將使用的方法。當我們認識到時間正在流逝,我們放棄了信念并拋棄了迭代過程。在恐慌狀態中,我們又回到了我們的老習慣。迭代開發多半沒有實際失敗。我們只是沒有給它一個成功的機會。
迭代測試在迭代開發的累積好處的每一個迭代中提供了可見的記號。當團隊共享增加的成功標準(例如,每一個迭代的進入和退出標準)時,站在正確的方向上是更加容易的。
因為我們根據出口標準持續監控結果,我們可以更容易地在迭代中調整我們的測試來達到我們的最終目標。例如,在中間迭代中,我們可以觀察我們關鍵的和高缺陷計數在增長,并且我們可以比修正它們更快地找到它們。因為我們早已經認識到這個趨勢,我們可以重新分配資源來加深對于關鍵路徑活動的關注。我們可以再分配研究“樂意擁有” 特性的開發人員來修正“發布定義” 特性中的缺陷,或者刪除與高缺陷計數有關的樂意擁有特性。
結論
我只接觸到了我們假設每天都會遇到的軟件開發的謬論中的少數一部分。如果我們假設做得越多,我們就會越少發現不可預知的事情——所有關于軟件測試的。
不幸的是,我們提到的謬論是非常誘人的。它們被偽裝成答案,并且它們方便地結束了對話。當我們人員不足并承受壓力時,接受假設作為事實是非常誘人的。
因為我們經常難以分辨謬論和事實,我們需要檢查我們的答案。這個簡單而有效的頌歌,總結了我已經在這篇文章中論述的所有東西,將有助于你保持在正確的軌道上:
迭代測試從來都沒有滿意的正確答案。
注解
1 在能力成熟度模型 (CMM,或CMMI)中,通過依靠少數幾個個人英雄主義的勞動典型的是成熟度 1 級的水平,也就是眾所周知的混亂級別。
原文轉自:http://www.anti-gravitydesign.com