軟件測試的目的及原則 軟件測試
一、軟件測試的目的
誤解1:軟件測試的目的是為了確保沒有Bug 這種看法反映了一種對于軟件本質的樂觀但從根本上錯誤的觀點。一個簡單的事實就是不存在“bug-free”的軟件。 為什么是這樣呢?首先,在等式的開發一邊,你必須面對時刻在變化的技術,一個復雜的而且經常有缺陷的應用設計,集成新的已存在的系統帶來的困難,等等。人本身的錯誤也是一個很大的因素。雖然現代思維應用開發工具可以自動生成代碼,但是在有些地方人必須參與到開發過程中,而人是會犯錯誤的。 而在等式的測試這一邊,不可能讓你的產品在送到你的用戶以前運行所有可能的測試來檢測出每一個可能的bug。 讓我們來看一個簡單的假定的例子。比如說你要測試一個這樣的程序: 接受3個整型的數值作為輸入,每一個數值的范圍在0到9之間。 在2種操作系統下運行。 可以訪問存儲在3個不同廠商中任何一個提供的數據庫中的數據。 我們計算一下,我們有1,000種可能的排列作為測試輸入。為了測試在每個操作系統上的每種排列,我們需要2,000個測試用例,另外再考慮到每種輸入在每個支持的數據庫運行一遍,我們需要6,000個測試用例。這個數字還沒有考慮到其他的測試情況,例如網絡故障,磁盤空間不足以及內存耗盡等等。所以實際上我們需要測試用例的數目要更大一些。 無疑,我們不得不接受這樣一個事實:我們只能生活在一個所有的軟件都有bug的世界當中。然而,我們沒有必要絕望。經過精心的計劃,我們可以選擇性地找出產品中最多出現危險以及對我們的用戶最重要的部分中的bug。下面是我發現的有效的一些步驟。 在你的計劃當中加入風險分析 正確理解你的客戶需求文檔本身就是一門科學(后面將會詳細講到)。如果你不能直接接觸到你的用戶--例如,通過客戶焦點小組,那么你就應該和你的客戶支持部門一起商討你的測試計劃,因為他們直接接觸到最終用戶。 要明白你的產品哪些部分處于危險當中同樣需要分析。變更是危險的主要來源;如果你引入了一個變更,你可能不注意地引入了一個新的bug或者發現一個已經存在的bug。因此,支持新功能的代碼一直是一個尋找危險的好地方。為了修正一個bug而修改的代碼也是這樣。而且,如果你在某個地方發現了bug,那么在附近潛藏著其他bug的可能性就很大。雖然你可能認為經過多年修正了很多bug的地方最后“清除干凈了”,這種想法只是在修正時發現了bug的根源的情況下才是正確的。如果bug的根源是糟糕的設計,而進行的修正只是一個簡單的補丁而不是從根本上解決這個問題,那么這個修正實際上可能引入了新的bug。另外,記?。杭词故腔凇案驹颉钡男拚灿锌赡軙l基礎性變更,暴露其他嚴重bug。 理解產品是如何工作的--和為何可能出故障 對一些測試者來說,第一個想做的就是看產品外在的可見的“行為”--將精力集中在他們的產品客戶將看到的部分。這樣做效力有限,因為他們沒有清楚的理解產品程序的邏輯,數據流等等,這些是用戶不可見的。為了能夠理解產品是如何工作的,以及怎樣會出故障,你必須看“罩子下面”并且在你的測試中用到你看到的東西。2 例如,如果你只看一個GUI,你可能看到程序通過一個格式化的HTML表格顯示一個特定的數據庫查詢的結果。然而,除非你知道這個表格的表示是一個Java數組對象,從服務器傳到客戶端,然后轉化為一個HTML表格,否則你就不會知道這里存在一個潛在的一個客戶端性能瓶頸的危險。如果一個用戶運行一個查詢,返回的記錄太多,就會導致客戶端在處理表格的時候像死機一樣。(我在幾年前是通過這樣的方法解決這個問題的:每次讓客戶端只接收一部分結果數據,并且明確地告訴用戶還有其他的數據未傳過來。) 如果有充足的時間設計和進行測試,你總是可以找到更多的bug。然而,如果那個bug好像對你的客戶影響不大,那就不值得花時間和精力去找到它。去搜索每一個可能導致系統在5,000年發生一次故障的bug是沒有意義的,因為那可能需要你花5,000年去運行所必要的測試。3 花時間去找出哪里可能藏有真正有影響的bug,并將測試集中于那些地方,會好很多。 理解客戶究竟會怎樣去使用產品 之前,我間接提到了通過直接接觸實際用戶或者通過你公司用戶服務部門去了解用戶需求的重要性。通過同樣的渠道,你也應該確認你的測試計劃是否反映了你用戶的系統配置,特殊需求以及吞吐/系統能力需求。 這也需要了解你的客戶的條件限制,這些限制將直接影響用戶怎樣使用你的產品。在我加入Rational之前,我的工作是有關一個Internet防火墻,它能夠支持常被稱之為“split-brained DNS”功能網絡配置功能。這個功能使用戶能夠在他們的防火墻后面維護一個私有的DNS服務器。然而我們發現,一些內部DNS服務器被錯誤的配置了,在我們沒有更正他們的DNS 配置之前,無法使防火墻正常工作。最后我們不得不更改我們的安裝工具使得即使在用戶的內網斷了的情況下防火墻仍能夠正常運行。這樣我們就可以把修理他們的網絡當做一個獨立的(收費的)任務。 現在讓我們轉到第二個誤解。如果我們接受了bug-free軟件真的是不存在的這一觀念,我們可以通過運行測試找到故障,那么我們要測試到出故障,對嗎?但是如果測試中出故障是一個好事情,那么我們是否能夠把它叫做“失敗”呢?
二、軟件測試的原則應該是:
(1)應當把“盡早地和不斷地進行軟件測試”作為軟件開發者的座右銘。
由于原始問題的復雜性,軟件的復雜性和抽象性,軟件開發各個階段工作的多樣性,以及參加開發各種層次人員之間工作的配合關系等因素,使得開發的每個環節都可能產生錯誤。所以不應把軟件測試僅僅看作是軟件開發的一個獨立階段,而應當把它貫穿到軟件開發的各個階段中。堅持在軟件開發的各個階段的技術評審,這樣才能在開發過程中盡早發現和預防錯誤,把出現的錯誤克服在早期,杜絕某些隱患,提高軟件質量。
(2)測試用例應由測試輸入數據和與之對應的預期輸出結果這兩部分組成。
測試以前應當根據測試的要求選擇在測試過程中使用的測試用例(Test case)。測試用例主要用來檢驗程序員編制的程序,因此不但需要測試的輸入數據,而且需要針對這些輸入數據的預期輸出結果。如果對測試輸入數據沒有給出預期的程序輸出結果,那么就缺少了檢驗實測結果的基準,就有可能把一個似是而非的錯誤結果當成正確結果。
(3)程序員應避免檢查自己的程序。
測試工作需要嚴格的作風,客觀的態度和冷靜的情緒。人們常由于各種原因具有一種不愿否定自己工作的心理,認為揭露自己程序中的問題總不是一件愉快的事。這一心理狀態就成為測試自己程序的障礙。另外,程序員對軟件規格說明理解錯誤而引入的錯誤則更難發現。如果由別人來測試程序員編寫的程序,可能會更客觀,更有效,并更容易取得成功。要注意的是,這點不能與程序的調(debuging)相混淆。調試由程序員自己來做可能更有效。
(4)在設計測試用例時,應當包括合理的輸入條件和不合理的輸入條件。
合理的輸入條件是指能驗證程序正確的輸入條件,而不合理的輸入條件是指異常的,臨界的,可能引起問題異變的輸入條件。在
試程序時,人們常常傾向于過多地考慮合法的和期望的輸入條件,以檢查程序是否做了它應該做的事情,而忽視了不合法的和預想不到的輸入條件。事實上,軟件在投入運行以,用戶的使用往往不遵循事先的約定,使用了一些意外的輸入,如用戶在鍵盤上按錯了鍵或打入了非法的命令。如果開發的軟件遇到這種情況時不能做出適當的反應,給出相應的信息,那么就容易產生故障,輕則給出錯誤的結果,重則導致軟件失效。因此,軟件系統處理非法命令的能力也必須在測試時受到檢驗。用不合理的輸入條件測試程序時,往往比用合理的輸入條件進行測試能發現更多的錯誤。
(5)充分注意測試中的群集現象。
測試時不要以為找到了幾個錯誤問題就已解決,不需繼續測試了。經驗表明,測試后程序中殘存的錯誤數目與該程序中已發現的錯誤數目或檢錯率成正比。根據這個規律,應當對錯誤群集的程序段進行重點測試,以提高測試投資的效益。
在所測程序段中,若發現錯誤數目多,則殘存錯誤數目也比較多。這種錯誤群集性現象,已為許多程序的測試實踐所證實。例如美國IBM公司的0s/370操作系統中,47 9/6的錯誤僅與該系統的4%的程序模塊有關。這種現象對測試很有用。如果發現某一程序模塊似乎比其他程序模塊有更多的錯誤傾向時,則應當花費較多的時間和代價測試這個程序模塊。
(6)嚴格執行測試計劃,排除測試的隨意性。
測試計劃應包括:所測軟件的功能,輸入和輸出,測試內容,各項測試的進度安排,資源要求,測試資料,測試工具,測試用例的選擇,測試的控制方式和過程,系統組裝方式,跟蹤規程,調試規程,以及回歸測試的規定等以及評價標準。對于測試計劃,要明確規定,不要隨意解釋。
(7)應當對每一個測試結果做全面檢查。
這是一條最明顯的原則,但常常被忽視。有些錯誤的征兆在輸出實測結果時已經明顯地出現了,但是如果不仔細地全面地檢查測試結果,就會使這些錯誤被遺漏掉。所以必須對預期的輸出結果明確定義,對實測的結果仔細分析檢查,抓住征候,暴露錯誤。
(8)妥善保存測試計劃,測試用例,出錯統計和最終分析報告,為維護提供方便。
原文轉自:http://www.anti-gravitydesign.com