本節書摘來自華章計算機《需求設計:建構使用者想要和需要的産品》一書中的第3章,第3.8節,作者: [英] 克裡斯·布裡頓(chris britton) 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
大型項目的測試會分成很多層。我們經常能看見那種包含單元測試、功能測試、回歸測試、元件測試、性能測試、系統測試及驗收測試的項目。無論測試能找到多少bug,它都要耗費大量的資源與時間。在software estimating rules of thumb這篇文章[19]中,capers jones提出了他所總結的“軟體開發成本動因定律”(law of software development cost drivers),該定律宣稱,“對于所有的軟體來說,查找及修複bug都是成本最高的活動。”順便再說一下,對于bduf項目來說,還有幾個成本比較高的活動排在該因素的後面,它們分别是:寫文檔、寫代碼、開會和管理。在軍事項目中,寫文檔會升至第一位。在靈活項目中,第二位和第四位互換。
測試有一個令人失望的特點,那就是它非常低效。其原因有很多:
測試通常緻力于證明程式已經實作了它所應該達成的功能,而很少會緻力于查找錯誤。如果我們發現了bug,那就會修複該bug并撰寫一項測試,以證明程式現在可以正常運作,然後,這項測試會反複地運作,于是,我們自然就會發現它每次都能夠運作通過。簡單來說,我們所測試的路徑,隻不過是程式最有可能走到的那些路徑而已。
測試,是由那些熟悉應用程式工作原理的人所編寫的。而使用該應用程式的人,并不知道它的工作原理,是以可能會采用一些與測試者不同的方式,來操作該應用程式。早在1989年,miller等就有一項驚人的發現,他們把一些胡亂生成的内容輸入給各種unix實用程式[20],然後看到其中有25%~33%的程式無法通過測試。
建構測試所需的工作量很大,是以我們不會建構太多的測試。
測試本身通常也含有一些錯誤。
有一些錯誤很難通過測試來檢查,例如,時機錯誤、因資料庫中缺失資料所引發的錯誤,以及由于網絡入侵而造成的安全問題等。
大部分的測試,都是在測試應用程式上面運作的,然而還有一些錯誤,則與版本不符或配置不當有關,這些錯誤發生在我們把應用程式移動到生産系統中的時候。
公司應該讓最優秀的人去實作一套良好的系統測試機制。我們也可以換一種說法:程式設計本領最強的人,不一定是最能把測試寫好的人。最适合寫測試的,應該是那種頗具創意,而且特别喜歡把應用程式搞壞的人。
有一次筆者聽到這樣一種說法:專業的古典音樂家與業餘的古典音樂家不同,後者隻要能把某段樂譜準确地彈完一遍,就不再繼續練習了,而前者則會反複練習,直到毫不出錯。這是兩種不同的境界,業餘人士隻滿足于我能彈好一遍就行,而專家追求的則是每次都能彈好。測試也與之類似。測試并不是隻保證應用程式能達到業餘水準,而是要按照專業的水準來要求它。為了暴露程式的故障點,筆者建議你采用以下做法:
試着令應用程式承擔大量的負載,尤其是要使應用程式感覺到,這些負載好像是多位使用者同時造成的。
試着在程式裡面引發故障,而且還要試着在錯誤恢複的過程之中引發故障。
在接縫處尋找故障,也就是要檢查部件之間的每一條依賴關系并對其進行測試。
如果應用程式已經發行,而且資料庫裡也已經有了真實的資料,那麼就試着編寫一些采用真實資料來運作的測試,同時可能還需要對這些資料做匿名處理。有許多測試都在反複地使用同一份資料,這些測試的編寫者尤其需要注意:如果資料庫發生了變化,那麼相應的資料可能也會有所改變。
想要制作一款高品質的程式,單靠測試是不夠的。還應該采取下列措施:
使用靜态分析器去分析代碼,以便找出其中從來沒有執行過的代碼及變量、還沒有初始化就直接使用的變量、有可能無法終止的循環,以及潛在的性能及安全問題。
使用代碼檢查機制。筆者建議執行兩個層面的代碼檢查,第一個層面是由團隊内的其他程式員來檢查,第二個層面是由系統測試組來檢查。前者應該幫助我們消除那些簡單的錯誤以及對系統配置方式的誤解,而後者則應該指出安全隐患等更為微妙的問題。
有統計資料表明,上面這些做法和測試一樣有效,它也能夠檢查出bug,而且這些bug還和那些經由測試所檢查出來的bug有所不同。
如果我們能夠很好地計算出bug的數量,那麼可能就會注意到,其中某一部分代碼會頻繁地出現bug,這部分代碼就好像燭光,而這些bug(程式錯誤/蟲子),則像是撲火的飛蛾。這一部分代碼需要更為詳細地檢視,而且有可能需要重寫。