微軟的軟體測試方法[轉載]

摘要:微軟的軟體測試方法[轉載]

Jeff Wang
Jeffwang@microsoft.com
BizTalk Server
微軟有限公司


(一)

      國內近年來關於軟體測試的問題和討論越來越活躍。但從總體上說交流軟體測試技術的多,而探討軟體測試方法的少。這裡的「技術」指的是具體的戰術問題,比如 說如何使用某種工具來解決某一特定測試問題,或是某一型別軟體有哪些測試手段等等。而這裡的「方法」指的是宏觀的戰略問題,或是叫方法論,這包括從軟體測 試的概念或理念,到企業軟體品質控制體系;從軟體測試的程序,到測試團隊的設定及其職責的界定等等。作為測試人員,熱衷於「技術」討論和交流是一件可喜可 賀的事。從中可以感覺到軟體測試在中國迅速發展的開端和潛力。但是作為企業的管理決策者,是否也應該以同樣的熱情來思考「方法」問題呢?特別是當一個軟體 企業的軟體測試從無到有,或是當企業已有一定的軟體測試的投入,但發現其實效並不顯著,甚至由於測試的引入而帶來了新的管理上的混亂。這個時候方法論的思 考,更有利於發現問題的根源。即便是一個基層的測試人員,當積累了一定的技術經驗後,也應該不時從日常的具體工作中走出來,在一個較高層次上進行回顧總結 和借鑒,並試著提出一些最佳化和改進的措施,這無論對專業上還是對事業上的成長都是非常有意義的。微軟在軟體測試方面有很多值得一提的經驗,在此我想以我 個人的體會和思考,同大家一同進行一些探討。
      這裡有一點須要特別說明,儘管微軟的方法已被微軟的實踐多次證明是成功的,非常有效的,但這並不意味著這些方法在中國的軟體企業中有廣泛的可行性。一種方 法是否可行還受到很多其它因素的影響,比如企業型別(微軟是生產平台軟體和泛用軟體產品的企業),企業管理體制,企業文化等等。所以我的目的只是給大家一 些思路和借鑒。

兩類經典的軟體測試方法
      在具體介紹微軟的軟體測試方法之前,我想首先從概念,或理念的層面上來理解究竟甚麼是軟體測試,目的是從中匯出微軟測試方法的理論根源。
傳統上認為軟體測試的方法從總體上分為兩類。第一類測試方法是試圖驗證軟體是「工作的」,所謂「工作的」就是指軟體的功能是按照預先的設計執行的;而第二類測試方法則是設法證明軟體是「不工作的」。
      提出第一類方法的代表人物是軟體測試領域的先驅Dr. Bill Hetzel(代表論著《The Complete Guide to Software Testing》),他曾於1972年6月在美國的北卡羅來納大學組織了歷史上第一次正式的關於軟體測試的論壇。他首先在1973年給軟體測試一個這樣的 定義:「就是建立一種信心,認為程式能夠按預期的設想執行。Establish confidence that a program does what it is supposed to do. 」後來在1983年他又將定義修訂為:「評價一個程式和系統的內容屬性或能力,並確定它是否達到預期的結果。軟體測試就是以此為目的的任何行為。Any activities aimed at evaluating an attribute or capability of a program or system. 」在他的定義中的「設想」和「預期的結果」其實就是我們現在所說的使用者需求或功能設計。他還把軟體的品質定義為「符合要求」。
      第一類測試可以簡單抽像地描述為這樣的程序:在設計規定的環境下執行軟體的功能,將其結果與使用者需求或設計結果相比較,如果相符則測試通過,如果不相符 則視為Bug。這一程序的終極目標是將軟體的所有功能在所有設計規定的環境完全執行,並通過。在軟體行業中一般把第一類方法奉為主流和行業標準。1990 年的IEEE/ANSI標準將軟體測試進行了這樣的定義:「就是在既定的狀況條件下,執行一個系統或組建,觀察記錄結果,並對其某些方面進行評價的程序。 The process of operating a system or component under specified conditions, observing or recording the results, and making an evaluation of some aspect of the system or component (IEEE/ANSI, 1990 [Std 610.12-1990]」這裡所謂「既定的狀況」也可理解為需求或設計。
      儘管如此,這一方法還是受到很多業界權威的質疑和挑戰。代表人物是Glenford J. Myers(代表論著《The Art of Software Testing》)。他認為測試不應該著眼於驗證軟體是工作的,相反應該首先認定軟體是有錯誤的,然後去發現盡可能多的錯誤。他還從人的心理學的角度論 證,將 「驗證軟體是工作的」作為測試的目的,非常不利於測試人員發現軟體的錯誤。於是他於1979年提出了他對軟體測試的定義:「就是以發現錯誤為目的而執行程 式的程序。The process of executing a program or system with the intent of finding errors.」 這就是軟體測試的第二類方法,簡單地說就是驗證軟體是「不工作的」,或是說是有錯誤的。他甚至極端地認為,一個成功的測試必須是發現Bug的測試,不然就 沒有價值。這就如同一個病人(假定此人確有病),到醫院做一項醫療檢查,結果各項指標都正常,那說明該項醫療檢查對於診斷該病人的病情是沒有價值的,是失 敗的。我並不完全同意這一看法。第二類軟體測試方法在業界也很流行,受到很多學術界專家的支援。大家熟悉的Ron Patton在《軟體測試》( 中文版由機械工業出版社出版,具說此書是目前國內測試新手入門的經典教材)一書的第10頁,有一個明確而簡潔的定義:「軟體測試員的目標是找到軟體缺陷, 盡可能早一些,並確保其得以修復。」有些軟體企業以Bug數量來作為考核測試人員業績的一項指標,其實就是接受了這樣的方法。

兩類方法的優劣對比
      雖然軟體測試總的目的是為了軟體產品的品質,但很明顯這兩類測試方法在具體目標、或指導思想上截然相反。由此也決定了它們在思路、程序和測重點上有很大的 差別,並各有利弊的。第一類測試方法以需求和設計為本,因此有利於界定測試工作的範疇,更便於部署測試的側重點,加強針對性。這一點對於大型軟體的測試, 尤其是在有限的時間和人力資源情況下顯得格外重要。而第二類測試方法與需求和設計沒有必然的關聯,如果計劃管理不當,測試活動很容易丟失重點,走入歧途。 第一類測試方法可以與軟體的架構和軟體開發的計劃相配合,使軟體測試活動逐層次的展開,從而使軟體的功能和品質有計劃地逐步完善和提高(關於測試的層次問 題,我會在今後的討論中專門介紹)。第二類測試方法不具備這種程序的漸進性。第一類測試方法的缺點是缺乏靈活性,不利於測試人員主觀能動性的發揮,正像 Myers先生所說,不容易找到軟體的錯誤(Bug)。而這方面正是第二類測試方法的長處。

微軟的原則

       正是因為認識到兩類測試方法各有利弊,微軟在軟體測試活動中將兩類方法結合起來,以第一類測試方法為基礎和主要線索,階段性地運用第二類測試方法。

  • 微軟的第一類測試

      微軟的第一類測試總體上說分為三個步驟進行:審核需求和設計—〉設計測試—〉實施執行測試。前文已述,第一類測試是以需求和設計為本來驗證軟體的正確性。 大家很自然的想到,需求和設計本身也有正確性的問題。依據不正確的需求和設計不可能開發出正確的軟體產品,測試也將是徒勞的。因此驗證需求和設計是微軟進 行第一類測試的第一步。有必要指出的是,這裡所說的需求和設計具體說來它一般包括:(1)由專案經理根據使用者要求(資訊來源於市場部門,使用者支援部門 等等)而編輯的需求字串(Requirement Specification);(2)由專案經理根據需求字串而編輯的功能設計字串(Functional Design Specification);(3)由開發人員根據功能字串而編輯的實施設計字串(Implementation Design Specification)。微軟的測試人員要參與所有這些字串的審核。作為測試人員,審核重點是檢查字串對使用者需求定義的完整性、嚴密性和功能設計 的可測性。同時這種審核對於測試人員也是一種熱身活動,使他們盡早地進入技術和業務狀態。第二步,測試人員要根據已審核通過的需求和設計編製測試計劃,設 計測試用例。在前面提到的三種字串中,功能設計字串是主要依據。原因很簡單,這類測試關心的是軟體是否能正確地實作功能,而不是這些功能如何被具體實施 的。從這裡大家可以看出這是典型的「黑盒測試」。確實微軟的測試主要是從使用者角度進行的黑盒測試。這一步的完成就意味著「測試計劃」和「測試用例設計」 兩個字串的完成。「測試計劃」 字串主要闡述測試的範疇、領域、方法、工具、資源和計劃時間表等等。「測試用例設計」字串要列出測試用例、每個用例的設定、執行步驟和預期結果。測試的這 兩個字串也要被專案經理和開發人員審核。這樣經過各種相互的審核,大家對專案形成了基本的共識。第三步的實施執行測試是整個開發程序中最長最複雜的一個階 段。從總體上說就是將上一步設計的測試用例按計劃付諸實施的程序。這包括編輯自動化測試程式、反覆執行自動化測試程式,也包括階段性執行手動測試用例。這 一階段的測試必須在周密的計劃下進行,在前面我已提到,這正是第一類測試的特點和長處。這種計劃性首先秉持在開發和測試的相互協調配合,根據產品的架構和 功能模組的依賴關係,按照專案的總體計劃共同推進。從測試的程序來看,總是先執行或執行簡單用例,然後再複雜用例;先驗證單一的基本功能,再綜合的端到端 的功能;先發現解決表面的,影響面大的Bug,再深層的,不容易重現的Bug。因此隨著專案開發和測試的處理序,產品的功能不斷完善,品質不斷提高。這裡 有一點要特別指出,有很多測試用例是要反覆執行的,特別是基本的自動化測試每一天,每一個Build上都要執行。儘管這些測試大多數情況下都是通過的,很 少再發現新的Bug,但其價值是顯而易見的,就是為了防止品質回歸。可見Myers的理論在這裡是不適用的。這一階段測試人員還有一項繁瑣但卻很重要的工 作,就是對已有的測試用例的維護。比如通常以下兩種情況下要新增一些測試用例,一是對於當初測試設計不周全的領域,二是對於外部的Bug(比如從Beta 客戶報告來的),沒有被現有測試用例所覆寫。當產品的功能設計出現更改時(在微軟這是常事),所涉及的測試用例當然也要相應地修改。

  • 微軟的第二類測試

     微軟的第二類測試是階段性的,常常根據需要而帶有隨機性和突擊性。對於這類測試,在微軟有一個專門的名稱:「Bug Bash(Bug大掃除)」。 Bug Bash通常發生在專案開發各階段(微軟叫里程碑)的末期,比如Beta版發佈前,劃出一個專門的時間段(通常1-3天),在這工作階段會議所有參與專案 的人員,集中完全精力,運用各方面的知識,盡完全智慧來搜尋專案的Bug。這是一個非常有意思的活動,但要組織好這樣的活動並非易事。一般有以下要點: (1)儘管這是一個測試活動,但參與者並不僅限於測試人員。專案經理,開發人員甚至於高層管理人員都應參加,如同全民動員。目的是要集思廣益;(2)要鼓 勵各部門,領域交叉搜索,因為新的思路和角度通常有助於發現更多的Bug;(3)為調動積極性,增強趣味性,可以適當引入競爭機制,比如當活動結束時,評 出發現Bug最多,發現最嚴重Bug的個人,給以物質和精神獎勵。(4)可以分專題展開,比如安全性、使用者界面可用性、國際化和本地化等等。微軟的第二 類測試除了Bug Bash外,經常還有一些專業性的測試,最典型的是針對安全性攻擊測試。一般會邀請公司內部,或業界的專家來搜尋產品的安全漏洞。 以上我從傳統軟體測試概念的角度,介紹了微軟的原則和兩類傳統測試方法的具體做法,及其側重點。這其實僅僅是一個基礎,一個很原始的基礎。軟體測試在微軟 軟體產品開發中的作用、地位遠不是這些原始的方法所能達到的,也不是傳統軟體測試概念所涵蓋的。微軟在軟體測試方面有很多特有的做法,和概念上的突破,比 如「軟體測試的資訊服務功能」、「以使用者為中心的宏觀品質體系」、「分級測試」、「專案的品質管制系統」、「Bug三方會審」、「測試自動化」和「軟體 測試的軟硬體—部門、團隊、人和基礎設施」等等。這些我會在以後的討論中分專題進行介紹。

(二)

      我在前一篇「微軟的軟體測試方法」中介紹了微軟的兩類基本測試方法,其基本思想大家應該是比較熟悉的,因為它們還只是傳統的軟體測試方法的綜合。所以單從 形式上,它並沒有秉持出對傳統框架的突破。但是從另一個層面來考察微軟軟體測試時,你會對一些基本的事實感到驚訝。比如,「微軟的測試人員和開發人員數量 大致相等或略多」,「微軟的產品成本中測試大約占40%以上」等等。人們會有疑問,僅僅是作為功能驗證和搜尋Bug的測試能消耗這麼大量的資源嗎?有必要 付出如此大的代價嗎?應該有理由相信,微軟作為一個軟體企業,其每一份投入都是有意義的,因此也可斷定微軟在軟體測試方面的努力一定超出傳統測試方法的範 疇。



歷史回顧

      為了更好的理解微軟體測試在方法和理念上的突破,我想首先回顧一下軟體開發和軟體測試的發展歷史,並從中揭示其必然性。Edward Kit 在他的暢銷書「Software Testing In The Real World : Improving The Process(1995, ISBN: 0201877562)」中將整個軟體開發歷史分為三個階段:


第一個階段是60年代及其以前,那時軟體規模都很小、複雜程度低,軟體開發的程序隨意。開發人員的Debug程序被認為是唯一的測試活動。其實這並不是現代意義上的軟體測試,當然一階段也還沒有專門測試人員的出現。


      第二個階段是70年代,這個階段開發的軟體仍然不複雜,但人們已開始思考開發流程問題,並提出「軟體工程Software Engineering」的概念。但是這一階段人們對軟體測試的理解僅限於基本的功能驗證和Bug搜尋,而且測試活動僅出現在整個軟體開發流程的後期,雖 然測試由專門的測試人員來承擔,但測試人員都是行業和軟體專業的入門新手。


      第三個階段是80年代及其以後,軟體和IT行業進入了大發展。軟體趨向大型化。與之相應,人們為軟體開發設計了各種複雜而精密的流程和管理方法(比如 CMM和MSF),並將「品質」的概念融入其中。軟體測試已有了行業標準(IEEE/ANSI ),它再也不是一個一次性的,而且只是開發後期的活動,而是與整個開發流程融合成一體。軟體測試已成為一個專業,需要運用專門的方法和手段,需要專門人才 和專家來承擔。



測試與開發的融合

      在這一歷史發展程序中,最值得注意的是測試與開發流程融合的趨勢。人們對這種融合也許並不陌生。比如測試活動的早期展開,讓測試人員參與使用者需求的驗 證,參加功能設計和實施設計的審核。再比如測試人員與開發人員的密切合作,隨著開發進展而逐步實施單元測試、模組功能測試和系統整合測試。的確這些都是測 試與開發融合的表現形式,而且初期的融合也只反映在這個層次上。90年代以後,軟體的規模和複雜程度迅速提高,這種形式上的融合也迅速走向更深層次,更具 實際意義。具體地說這種融合就是整個軟體開發活動對測試的依賴性。傳統上認為,只有軟體的品質控制依賴於測試,但是現代軟體開發的實踐證明,不僅軟體的品 質控制依賴於測試,開發本身離開測試也將無法推進,專案管理離開了測試也從根本上失去了依據。在微軟,測試的確有這樣的地位和作用。這就是為什麼微軟在軟 體測試上有如此大的投入。



開發對測試的依賴

      現代軟體開發,特別是大型軟體開發通常會遇到以下兩個問題:


(1)在開發初期,如何能夠展開大規模團隊,群體齊頭並進,而同時保持開發的有序性。從而有效利用資源,縮短開發週期。


(2)在開發後期,如何解決深層次的Bug,如何面對設計更改,而能夠保證產品的品質不出現或少出現回落。


對於小型簡單的軟體,這兩個問題也存在,但不突出,而且容易解決。但對於複雜的大型軟體的開發,這兩個問題常常會成為難以逾越的障礙。 通常大型專案的功能豐富,但架構、層次也會相當複雜。


穩 妥的開發方式是,一次投入少量的人員,逐層開發,逐層穩定。但這種方式顯然資源利用率低,開發週期長,不能滿足現代軟體和IT行業高速發展、瞬息萬變的需 要。因此大型專案需要大型團隊。在微軟,產品開發團隊(主要包括開發、測試和專案管理)一般都有百人以上規模,有些產品甚至上幾千人 (Windows2000的開發部門曾有3000多人)。這樣大規模的人力資源作用在一個動態的,內部相互洽詢的系統中,若沒有有效的協同,其混亂是不可 避免的。試想,有兩個開發人員,分別在開發兩個不同的功能模組,其相互有依賴關係。為了相互協調,他們可以隨時進行當面討論。如果這種關係發生在五個開發 人員和五個功能模組之間,這種協調就只能通過定期的會議來進行。而一個大型專案,會有許許多多這樣的關係,而且很多時候這種關係有著不確定性和不可預見 性。當一個開發人員編輯一段新的程式碼或對已有程式碼進行改動和調整時,他(或她)常常無法確定,或無法完全確定究竟有哪些相關的模組會受到影響,以及在 什麼請況下這種影響會帶來什麼結果。因為系統的複雜性已遠遠超出了人的邏輯思維、技能和經驗所能力及的範疇。因此這種傳統的協調手段是遠不能滿足需要的。


      在微軟,這種協調是通過測試來實作的。具體來說就是:每日建造+自動化測試。關於每日編譯和自動化測試,我將來會作專門介紹,這裡簡單的說就是每天都建造 一個新版本,每個版本都要執行通過一定量的自動測試用例,以檢驗當天工作的品質。這裡所說的品質當然有一般意義上品質的概念,但同時它也反映專案在開發程 序中的整體協調性。


      自動測試的最大優點在於它的高度可重複性。一個理想的自動測試系統能夠讓人隨時、方便和迅速的執行大量的測試用例。因此一個開發人員可以通過檢查當天的自 動測試結果來分析前一天程式碼的品質(事後檢查),也可以在當天存入程式碼前,先執行自動測試以進一步確存檔存盤入程式碼的品質(事前檢查)。


在 微軟,每日建造都是在午夜開始,完成後緊接著就是全面的自動測試,到早晨上班時間之前就會把結果自動通過e-mail等方式傳送出來。開發人員上班後的第 一件事往往就是檢查測試結果。如果沒有問題就會開始新的工作。如果有測試有用例沒有通過,開發人員則必須協同測試人員一起立刻找出原因,解決後才能開始新 的程式碼。有時一個小的失誤會引起大面積的測試用例失敗,很大一部分開發團隊會受到影響。為盡量避免這種情況,要求開發人員在存入程式碼之前先在自己的個 人建造版本上執行一定量的自動測試,完全通過後在存入。如開發人員沒有按照這樣的要求,而擅自存入品質不高的程式碼而造成大量測試失敗,這種不負責任的行 為是要受到嚴厲批評的。從這一程序可以看出,開發人員依賴測試來保證開發工作的品質,使開發整體地協調地向前推進。


      當開發進入後期階段,儘管專案已總體成型,開發人員也會不時遇到一些技術上的挑戰。比如一些Bug的解決涉及對專案深層次結構的調整;再比如由於客戶回饋 的意見造成設計的修改。每一次這樣的修改和調整事實上都是對一個穩定系統的破壞,如果處理不當往往一個Bug的修改會產生很多新的Bug,就像一系列聯鎖 的惡性重複。很多專案工期的延誤都是這樣造成的。要避免或至少將這種破壞減少到最低限度,開發人員首先需要知道這種破壞的影響面。在這裡單靠開發人員自身 的邏輯思維、技能和經驗是遠遠不夠的,自動測試再一次成為一種有效的工具。往往開發人員會制定不止一個方案,對每個方案上都執行一遍同樣一套自動測試用 例,然後比較結果,選出最佳方案。自動測試在這方面所起的作用不僅在產品的開發程序中,它還延續到產品發佈後。產品支援部門在為客戶提供應急解決方案時也 要依賴自動測試。



管理對測試的依賴

      在微軟,軟體專案管理的主要線索就是Bug的管理,其中最直接具體的管理活動就是「Bug三方討論會(Bug Triage)」。會議一般由專案管理Program Manager(簡稱PM)來主持,有開發人員和測試人員參加(所以叫三方會議)。會上對每個新產生的Bug進行討論,並決定(1)是否接受這個Bug; (2)Bug的嚴重層級和優先等級別;(3)Bug由誰來負責,是由測試提供進一步詳細資訊,還是交由開發人員解決,以及大致的解決方案等等。會議還要對 老的Bug檢查解決進度。這種討論會常常會發生爭論,要求測試人員具有足夠的技術基礎和使用者經驗,來捍衛產品的品質。可以說專案開發到了某一階段後就是 由這種Bug的管理所驅動的。這其中的原動力來自測試。 專案管理中一項非常重要但也十分困難的工作是衡量專案的進度,包括判斷專案的狀態,確定專案是否能預期完成。這方面,測試提供了兩個非常重要的參數,一個 是Bug數量的趨勢,另一個是測試結果的趨勢。 Bug趨勢就是將每天新產生的Bug數和每天被解決的Bug數標成一個趨勢圖表。一般在專案的開始階段新生Bug數曲線會呈上升趨勢,到專案中後期被解決 Bug數曲線會趨於上升,而新生Bug數曲線應下降,到專案最後,兩條曲線都趨向於零。PM會持續觀察這張圖表,確保專案健康發展,同時通過分析預測專案 Bug趨於零的時間。在一定的歷史經驗的基礎上分析使用這一圖表會得到很多有價值的資訊,比如說,可分析開發和測試在人力資源的配比上是否恰當,可以分析 出某個嚴重的Bug所造成的專案品質的波動。


      每天的自動測試結果同樣可以形成類似的圖表。它同樣非常有助於瞭解目前專案的品質狀況,開發測試進度。 由測試產生的這些資料不僅在專案開發程序中為專案管理提供有效的依據,而且也是產品通過發佈的必要條件。在微軟,每個產品都要經過評審才能通過發佈。前面 介紹的幾個圖表是發佈評審的重要內容,如果從圖表中發現臨評審前還出現過較大的品質波動,評審人員一定會對此提出質疑。 因此軟體專案管理依賴軟體測試提供其基本的管理段落。 可以說,現代大型軟體開發程序中開發和管理對測試的依賴性是測試與開發流程融合的一個根本因素。從另一個角度看,測試與開發流程融合決不僅僅是簡單的時間 上的同步,更不是雙方空間上的接近,而是這種內在的依存關係的外在表現。開發對測試的這種依賴性對測試和測是人員提出了更高的要求。在理念上,軟體測試已 遠不僅僅只是軟體功能的驗證和Bug的搜尋;在具體方法上,自動測試和測試工具的使用已成為基本的要求。在微軟,測試不僅使用一些泛用的工具,每一個產品 還有專門開發的專用工具庫,測試的程式碼量常常超過專案本身的程式碼量。


      一個軟體企業要提高其軟體開發的能力,特別是針對大型軟體的大規模的快速開發能力,在測試方面對傳統理念和方法進行突破是必要的。微軟的實踐就是一個很好的印證。