50126实现
第7章? 實現
?
實現:編碼和測試的統稱。
編碼:把軟件設計結果翻譯成用某種程序設計語言書寫的程序。
?
程序的質量主要取決于:
? 軟件設計的質量。
? 所選用的程序設計語言的特點及編碼風格也將對程序的可靠性、可讀性、可測試性和可維護性產生深遠的影響。
? 軟件測試也是保證軟件質量的關鍵步驟,它是對軟件規格說明、設計和編碼的最后復審。
?
?
7.1? 編碼 ?
7.1.1? 選擇程序設計語言
? 編碼之前的一項重要工作:
???? 就是選擇一種適當的程序設計語言。
? 高級語言
??? 用高級語言寫的程序容易閱讀,容易測試,容易調試,容易維護。
?
選用高級語言的實用標準:
(1) 系統用戶的要求。選擇用戶熟悉的語言。
(2) 可以使用的編譯程序。運行目標系統的環境中可提供的編譯程序往往限制了所選用語言的范圍。
(3) 可以得到的軟件工具。某種語言是否有支持程序開發的軟件工具可以利用。
(4) 工程規模。
(5) 程序員的知識。應該選擇一種已經為程序員所熟悉的語言。
(6) 軟件可移植性要求。
(7) 軟件的應用領域。
?
7.1.2? 編碼風格
好程序的標準:
??? 代碼的邏輯:簡明清晰、易讀易懂。
故編碼應該遵循下述規則:
? 程序內部的文檔
? 數據說明
? 語句構造
? 輸入輸出
? 效率
?? 程序內部的文檔
?
程序內部的文檔包括:恰當的標識符、適當的注解
和程序的視覺組織等。
???????????????? 含義鮮明的名字
???????????????? 正確的注解
???????????????? 縮寫規則一致
??? 程序清單的布局對于程序的可讀性也有很大影
響,應該利用適當的階梯形式使程序的層次結構
清晰明顯。
?
?
2.? 數據說明
?數據說明的次序應該標準化。
???? 有次序就容易查閱,因此能夠加速測試、調試和維護的過程。
??????? 先按類型
??????? 再按字母
?復雜的數據結構,應該用注解說明用程序設計語言實現這個數據結構的方法和特點。
?
?
3. 語句構造
?簡單而直接
不要為了節省空間而把多個語句寫在同一行;
盡量避免使用復雜的條件;
盡量減少使用“非”條件;
避免大量使用循環嵌套和條件嵌套;
利用括號使邏輯表達式或算術表達式的運算次序清晰直觀。
?
4. 輸入輸出
?對所有輸入數據都進行檢驗;
?檢查輸入項重要組合的合法性;
?保持輸入格式簡單;
?使用數據結束標記,不要要求用戶指定數據的數目;
?明確提示交互式輸入的請求,詳細說明可用的選擇或邊界數值;
?當程序設計語言對格式有嚴格要求時,應保持輸入格式一致;
?設計良好的輸出報表;
?給所有輸出數據加標志。
?
5.? 效率
主要討論程序運行時間和輸入輸出對效率的影響。
(1) 輸入輸出的效率
???? 簡單清晰是提高人機通訊效率的關鍵。
???? 如輸入輸出很難被人理解,將降低效率。
(2) 程序運行時間
影響源程序的效率的因素:
?算法的效率;
?寫程序的風格。(對程序的執行速度和存儲器要求產生影響)
因此寫程序時可應用下述規則:
?
寫程序時可應用下述規則:
?寫程序之前先簡化算術的和邏輯的表達式;
?仔細研究嵌套的循環,以確定是否有語句可以從內層往外移;
?盡量避免使用多維數組;
?盡量避免使用指針和復雜的表;
?使用執行時間短的算術運算;
?不要混合使用不同的數據類型;
?盡量使用整數運算和布爾表達式。
?
為什么要有編碼規范
編碼規范對于程序員而言尤為重要,原因:
? 一個軟件的生命周期中,80%的花費在于維護;
?幾乎沒有任何一個軟件,在其整個生命周期中,均由最初的開發人員來維護;
?編碼規范可以改善軟件的可讀性,可以讓程序員盡快而徹底地理解新的代碼。
??? 為了執行規范,每個軟件開發人員必須一致遵守編碼規范。
?
7.2? 軟件測試基礎
7.2.1? 軟件測試的目標
G.Myers給出了關于測試的一些規則,這些規則也可以看作是測試的目標或定義。
(1) 測試是為了發現程序中的錯誤而執行程序的過程;
(2) 好的測試方案是極可能發現迄今為止尚未發現的錯誤的測試方案;
(3) 成功的測試是發現了至今為止尚未發現的錯誤的測試。
? 測試是在精心控制的環境下執行程序,以發現程序中的錯誤,給出程序可靠性的鑒定。
?
7.2.1? 軟件測試的目標
?測試的正確定義是:“為了發現程序中的錯誤而執行程序的過程”。
?錯誤的認識:
??? “測試是為了表明程序是正確的”,
??? “成功的測試是沒有發現錯誤的測試” 。
?正確認識測試的目標是十分重要的,測試目標決定了測試方案的設計。
??? 如果為了表明程序的正確,就會設計一些不易暴露錯誤的測試方案;
??? 如果是為了發現程序中的錯誤,就會設計出最能暴露錯誤的測試方案。
7.2.2? 軟件測試準則
(1) 所有測試都應該能追溯到用戶需求。
??? 軟件測試的目標是發現錯誤,最嚴重的錯誤是導致程序不能滿足用戶需求。
(2) 應該遠在測試開始之前就制定出測試計劃。
??? 在完成需求模型時,就著手制定測試計劃,
??? 在建立了設計模型后,就開始設計詳細的測試方案。
(3) 應該從“小規模”測試開始,并逐步進行“大規模”測試。
??? 先測試單個程序模塊,再測試集成模塊,最后在整個系統中尋找錯誤。
(4) 應該由獨立的第三方從事測試工作。
??? 軟件工程師不能承擔全部測試工作,主要承擔模塊測試工作。
(5) 窮舉測試是不可能的。
窮舉測試:把程序所有可能的執行路徑都檢查一遍的測試。
??? 即使是一個中等規模的程序,其執行路徑的排列數也十分龐大。因此,測試只能證明程序中有錯誤,不能證明程序中沒有錯誤。
?
? 假設一個程序P有輸入量X和Y及輸出量Z。在字長為32位的計算機上運行。若X、Y取整數,按黑盒方法進行窮舉測試:
?
? 可能采用的
? 測試數據組:
??? 232×232
???? =264??
?如果測試一組數據需要1毫秒,一年工作365×24小時,完成所有測試需5億年。
?
?
7.2.3? 測試方法
?黑盒測試:指在軟件界面上進行的測試。一般用來證實軟件功能的可操作性;證實能很好的接收輸入,并正確地產生輸出;以及證實對外部信息完整性的保持。
?
?白盒測試:對程序細節進行嚴密檢驗,對軟件的邏輯路徑進行測試。
?
黑盒測試法:把程序看作一個黑盒子,完全不考慮程序的內部結構和處理過程。只檢查程序功能是否按照規格說明書的規定正常使用。
黑盒測試又稱為功能測試。
?
白盒測試法:把程序看成裝在一個透明的白盒子里,測試者完全知道程序的結構和處理算法,用于檢測程序中的主要執行通路是否都能按預定要求正確工作。
白盒測試又稱為結構測試。
?
7.2.4? 測試步驟
1. 模塊測試
??? 把每個模塊作為一個單獨的實體來測試。
??? 模塊測試通常又稱為單元測試。在測試中所發現的往往是編碼和詳細設計的錯誤。
?
2. 子系統測試
??? 把經過單元測試的模塊放在一起形成一個子系統來測試。
??? 模塊相互間的協調和通信是這個測試過程中的主要問題,著重測試模塊的接口。
?
3. 系統測試
??? 把經過測試的子系統裝配成一個完整的系統來測試。
??? 驗證系統能否提供需求說明書中指定的功能,動態特性是否符合預定要求。其中發現的往往是軟件設計中的錯誤,也可能是需求說明中的錯誤。
??? 子系統測試和系統測試,都兼有檢測和組裝兩重含義,通常稱為集成測試。
?
4. 驗收測試
??? 把軟件系統作為單一的實體進行測試,測試內容與系統測試基本類似,但它是在用戶積極參與下進行的,而且主要使用實際數據進行測試。
??? 目的是驗證系統確實能夠滿足用戶的需要,其中發現的往往是系統需求說明書中的錯誤。
??? 驗收測試也稱為確認測試。
?
5. 平行運行
平行運行:就是同時運行新開發出來的系統和將被它取代的舊系統,以便比較新舊兩個系統的處理結果。
這樣做的具體目的有如下幾點:
(1) 可以在準生產環境中運行新系統而又不冒風險;
(2) 用戶能有一段熟悉新系統的時間;
(3) 可以驗證用戶指南和使用手冊之類的文檔;
(4) 能夠以準生產模式對新系統進行全負荷測試,進一步驗證性能指標。
?
7.2.5? 測試階段的信息流
測試階段的的輸入信息有兩類:
?(1)軟件配置,包括需求說明書、設計說明書和源程序清單等;
(2)測試配置,包括測試計劃和測試方案。
測試方案包括:
?測試用例:測試時使用的輸入數據;
?每組輸入數據預定要檢驗的功能,以及每組輸入數據預期應該得到的正確輸出。
??? 圖7.1
??? 測試結果和預期結果不一致,程序中可能有錯誤,進入調試階段。由程序的編寫者負責調試。
?
圖7.1 測試階段的信息流
?
?如果經常出現要求修改設計的嚴重錯誤,那么軟件的質量和可靠性是值得懷疑的。
?
?如果軟件功能完成得很正常,遇到的錯誤也很容易改正,仍然應該考慮兩種可能:
?(1)軟件的可靠性是可以接受的;
?(2)所進行的測試尚不足以發現嚴重的錯誤。
?
?如果經過測試,一個錯誤也沒有被發現,則很可能是對測試配置思考不充分,以致不能暴露軟件中潛藏的錯誤。
?
?
7.3? 單元測試
??? 單元測試主要使用白盒測試技術,而且對多個模塊的測試可以并行地進行。
?
7.3.1? 測試重點
1. 模塊接口
??? 首先應該對通過模塊接口的數據流進行測試,如果數據不能正確地進出,所有其他測試都是不切實際的。
2. 局部數據結構
?? 局部數據說明、初始化、默認值等方面是否正確。
3. 重要的執行通路
?? 由于不可能進行窮盡測試,在單元測試期間選擇最有代表性、最可能發現錯誤的執行通路進行測試。
4. 出錯處理通路
??? 好的設計應該能預見出現錯誤的條件,并且設置適當的處理錯誤的通路。
??? 應該認真測試這種通路能否正確運行。
5. 邊界條件
??? 邊界測試在單元測試中非常重要。軟件常常在它的邊界上失效。
??? 使用剛好小于、剛好等于和剛好大于最大值或最小值的測試方案,非常可能發現軟件中的錯誤。
?
測試的過程
?程序的測試一般按三種方式進行:
靜態分析
動態測試
自動測試
?
?測試的過程,先進行靜態分析,然后進行動態測試;在某些特殊情況下,也可以借助自動測試工具對程序進行查錯。
?靜態分析:是指不執行程序,而只由人工對程序文本進行檢查,通過閱讀和討論,分析和發現程序中的錯誤。
?靜態分析是一種卓有成效的測試方法,大約30%—70%的邏輯設計錯誤和編碼錯誤可以通過靜態分析檢查出來。又稱代碼審查。
?
7.3.2? 代碼審查
?討論:是由一些有經驗的測試人員閱讀程序文本及有關文檔,對程序的結構與功能、數據的結構、接口、控制流以及語法進行討論和分析,從而揭示程序中的錯誤。
?走查:是由測試人員用一些測試用例沿程序邏輯運行,并隨時記錄程序的蹤跡;然后進行分析,發現程序中的錯誤。
?
測試的過程
?程序的動態分析:
?? 使用測試用例在計算機上運行程序,使程序在運行過程中暴露錯誤。
?自動測試工具:
?? 是人們編制的用于測試的軟件,并用它來代替人工測試。
?
7.3.3? 計算機測試
??? 模塊并不是一個獨立的程序,因此必須為每個單元測試開發驅動軟件和(或)存根軟件。
?驅動程序:也稱“主程序”,它接收測試數據,把這些數據傳送給被測試的模塊,并且印出有關的結果。
?存根程序:也稱“虛擬子程序”,代替被測試的模塊所調用的模塊。
??? 它使用被它代替的模塊的接口,可能做最少量的數據操作,印出對入口的檢驗或操作結果,并且把控制歸還給調用它的模塊。
?
對最小的軟件設計單元——模塊的驗證工作
?
例:圖7.2是一個正文加工系統的部分層次圖,假定要測試其中編號為3.0的關鍵模塊——正文編輯模塊。
?
?需要有一個測試驅動程序來調用它。
??? 說明必要的變量,接收測試數據——字符串,并且設置正文編輯模塊的編輯功能。
?存根程序簡化地模擬下層模塊,完成具體的編輯功能。可只用一個存根程序模擬正文編輯模塊的所有下層模塊。
?
圖7.2 正文加工系統的層次圖
?
?
代碼審查比計算機測試優越之處:
?一次審查會上可以發現許多錯誤;
?用計算機測試的方法發現錯誤之后,通常需要先改正這個錯誤才能繼續測試,因此錯誤是一個一個地發現并改正的。
?
??? 人工測試和計算機測試互相補充,相輔相成,缺少其中任何一種方法都會使查找錯誤的效率降低。
?
7.4? 集成測試
集成測試:把模塊按照設計要求組裝起來的同時進行測試。
主要目標:是發現與接口有關的問題。與系統測試類似。
?
組裝模塊有兩種方法:
1.非漸增式測試(整體拼裝):
? 首先對每個模塊分別進行模塊測試,然后再把所有模塊組裝在一起進行測試,最終得到要求的軟件系統;
?
?
?
?
2.漸增式測試(增量集成):
?首先對一個個模塊進行模塊測試,然后將這些模塊逐步組裝成較大的系統;
?在組裝的過程中邊連接邊測試,以發現連接過程中產生的問題
?通過增殖逐步組裝成為要求的軟件系統。
?
?
兩種方法優缺點:
非漸增式測試:
??? 一下子把所有模塊放在一起,并把龐大的程序作為一個整體來測試,測試者面對的情況十分復雜,會遇到許多錯誤,改正錯誤更是極端困難。而且改正一個錯誤之后,馬上又會遇到新的錯誤。
漸增式測試:
??? 它把程序劃分成小段來構造和測試,比較容易定位和改正錯誤;對接口可以進行更徹底的測試。
??? 故普遍采用漸增式測試方法。
??? 當使用漸增方式組裝模塊時,有自頂向下和自底向上兩種集成策略。
?
7.4.1? 自頂向下集成
?將模塊按系統程序結構,沿控制層次自頂向下進行組裝。從主控制模塊開始。
?
?在測試過程中較早地驗證了主要的控制和判斷點。
?
?選用按深度方向測試的方式,可以首先實現和驗證一個完整的軟件功能。
???
? 或使用深度優先策略,或使用寬度優先策略。
?
?
?
7.4.1? 自頂向下集成
由下述4個步驟完成:
第一步,對主控制模塊進行測試,測試時用存根程序代替所有直接附屬于主控制模塊的模塊;
第二步,根據選定的結合策略(深度優先或寬度優先),每次用一個實際模塊代換一個存根程序;
第三步,在結合進一個模塊的同時進行測試;
第四步,為了保證加入模塊沒有引進新的錯誤,需要進行回歸測試(全部或部分地重復以前做過的測試)。
上述第二步到第四步實質上構成了一個循環.
?
?
圖7.3 自頂向下寬度優先結合
7.4.2? 自底向上集成
?從程序模塊結構的最底層的模塊( 原子模塊)開始組裝和測試。
?因為是自底向上組裝模塊,對于一個給定層次的模塊,它的子模塊已經組裝并測試完成,所以不再需要存根程序。在測試過程中需要從子模塊得到的信息可以直接運行子模塊得到。
?
?
用下述四個步驟完成:
第一步,把低層模塊組合成實現某個特定的軟件子功能的族;
第二步,寫一個驅動程序,協調測試數據的輸入和輸出;
第三步,對由模塊組成的子功能族進行測試;
第四步,去掉驅動程序,沿軟件結構自下向上移動,把子功能族組合起來形成更大的子功能族。
上述第二步到第四步實質上構成了一個循環。圖7.4
如果軟件結構的頂部兩層用自頂向下的方法組裝,可以明顯減少驅動程序的數目,而且族的結合也將大大簡化。
?
圖7.4 自底向上結合
7.4.3? 不同集成測試策略的比較
???? 自頂向下測試方法的優點:
?不需要測試驅動程序,
?能夠在測試階段的早期實現并驗證系統的主要功能,
?能在早期發現上層模塊的接口錯誤。
?
???? 自頂向下測試方法的缺點:
?是需要存根程序,
?低層關鍵模塊中的錯誤發現較晚,
?用這種方法在早期不能充分展開人力。
??? 自底向上優缺點與自頂向下剛好相反。
?
通常采用混合策略:
(1) 改進的自頂向下測試方法。
?基本上使用自頂向下的測試方法,
?早期,對少數關鍵模塊使用自底向上的測試方法。
?
優點:
?具備自頂向下方法的優點;
?能在測試的早期發現關鍵模塊中的錯誤;
?
缺點:
?測試關鍵模塊時需要驅動程序。
?
(2) 混合法。
?較上層使用的自頂向下方法;
?較下層使用的自底向上方法。
兼有兩種方法的優點和缺點,最好的折衷方法。
?
7.4.4? 回歸測試
??? 在集成測試過程中每當一個新模塊結合進來時,程序就發生了變化,這些變化有可能使原來工作正常的功能出現問題。
回歸測試:重新執行已經做過測試的某個子集,以保證上述這些變化沒有帶來非預期的副作用。
?
7.5? 確認測試
也稱為驗收測試。
目標:驗證軟件的有效性。發現那些只有最終用戶才能發現的錯誤。
驗證:保證軟件正確地實現了某個特定要求的一系列活動;
確認:為了保證軟件確實滿足了用戶需求而進行的一系列活動。
軟件的有效性: 如果軟件的功能和性能如同用戶所合理期待的那樣,軟件就是有效的。
軟件有效性的標準:需求分析階段產生的軟件需求規格說明書,它是確認測試的基礎。
?
?Alpha測試
??? 由一個用戶在開發者的場所來進行的測試,軟件在開發者對用戶的指導下進行測試,開發者負責記錄錯誤和使用中出現的問題。
?Beta測試
??? 由軟件的最終用戶在一個或者多個用戶場所來進行,開發者不在場,用戶記錄問題。
?
7.6? 白盒測試技術
設計測試方案是測試階段的關鍵技術問題。
測試方案:
?包括測試目的(預定要測試的具體功能),
?應該輸入的測試數據和預期的結果。
測試用例:由測試輸入數據及與之對應的輸出結果組成。
?測試用例設計的好壞直接決定了測試的效果和結果。因此在軟件測試活動中最關鍵的步驟就是設計有效的測試用例。(因為不可能進行窮盡的測試)
?測試用例可以針對黑盒測試設計用例,也可以針對白盒測試設計用例。
?
白盒測試技術:用白盒方法測試軟件時設計測試數據的典型技術。
黑盒測試技術:用黑盒方法測試軟件時設計測試數據的典型技術。
?
白盒測試的目的:
? 保證一個模塊中的所有獨立路徑至少被執行一次;
?對所有的邏輯值均需要測試真、假兩個分支;
?在上下邊界及可操作范圍內運行所有循環;
?檢查內部數據結構以確保其有效性。
?
白盒測試的主要方法
? 邏輯驅動測試(邏輯覆蓋)
? 基本路徑測試
??????
?主要用于軟件驗證。
?用程序設計的控制結構導出測試用例。
?
7.6.1? 邏輯覆蓋
邏輯覆蓋:是對一系列測試過程的總稱。這組測試過程逐漸進行越來越完整的通路測試。
覆蓋:測試數據執行源程序的過程。
?
覆蓋源程序語句的詳盡程度存在不同的覆蓋標準:
?語句覆蓋
?判定覆蓋
?條件覆蓋
?判定/條件覆蓋
?條件組合覆蓋
?
例:圖7.5所示的程序流程圖描繪了一個被測模塊的處理算法。
? ?
圖7.5 被測試模塊的流程圖
?
1. 語句覆蓋
語句覆蓋的含義:選擇足夠多的測試數據,使被測程序中每個語句至少執行一次。
??? 為了使每個語句都執行一次,程序的執行路徑應該是sacbed。
??? 需要輸入下面的測試數據:
??? A=2,B=0,X=4( X可以是任意實數)
?
語句覆蓋缺點:
?對程序的邏輯覆蓋很少;
?語句覆蓋只關心判定表達式的值;
?沒有分別測試判定表達式中每個條件取不同值時的情況。
語句覆蓋是很弱的邏輯覆蓋標準。
?
2. 判定覆蓋
又叫分支覆蓋。
含義:不僅每個語句必須至少執行一次,而且每個判定的每個分支都至少執行一次。
需要輸入下面的測試數據:
??? A=3,B=0,X=3(1)??? (路徑是:sacbd)
??? A=2,B=1,X=1??? (路徑是:sabed)
??? 判定覆蓋比語句覆蓋強,但是對程序邏輯的覆蓋程度仍然不高,只覆蓋了程序全部路徑的一半。
還差: sacbed,sabd
?
3. 條件覆蓋
含義:不僅每個語句至少執行一次,而且使判定表達式中的每個條件都取到各種可能的結果。
測試數據使a點有下述各種結果:
???? A>1,A≤1,B=0,B≠0.
測試數據使b點有下述各種結果:
???? A=2,A≠2, X>1, X≤1.
需要輸入下面的測試數據:
??? A=2,B=0,X=1??? (路徑是:sacbed)
??? A=1,B=1,X=2??? (路徑是:sabed )??? (少bd分支)
??? 條件覆蓋通常比判定覆蓋強,它使判定表達式中每個條件都取到了兩個不同的結果;不一定包含判定覆蓋.
??? 判定覆蓋只關心整個判定表達式的值。
?
含義:不僅每個語句至少執行一次,而且使判定表達式中的每個條件都取到各種可能的結果。
測試數據使a點有下述各種結果:
?? ??A>1,A≤1,B=0,B≠0.
測試數據使b點有下述各種結果:
???? A=2,A≠2, X>1, X≤1.
另一組測試數據:
??? A=2,B=0,X=4??????? (路徑是:sacbed)
??? A=1,B=1,X=1??????? (路徑是:sabd )
? 包含了判定覆蓋。
?
4. 判定/條件覆蓋
??? 判定覆蓋不一定包含條件覆蓋,條件覆蓋也不一定包含判定覆蓋。
因為:判定表達式中的每個條件都取到各種可能的結果,但不能保證每個判定表達式也都取到各種可能的結果。
提出了判定/條件覆蓋。
判定/條件覆蓋:一種能同時滿足這兩種覆蓋標準的邏輯覆蓋。
含義:選取足夠多的測試數據,使得判定表達式中的每個條件都取到各種可能的值,而且每個判定表達式也都取到各種可能的結果。
有時判定/條件覆蓋并不比條件覆蓋更強。
?
測試數據使a點有下述各種結果:
???? A>1,A≤1,B=0,B≠0.
測試數據使b點有下述各種結果:
???? A=2,A≠2, X>1, X≤1.
測試數據:
??? A=2,B=0,X=4??????? (路徑是:sacbed)
??? A=1,B=1,X=1??????? (路徑是:sabd )
也符合條件覆蓋。
有時判定/條件覆蓋并不一定比條件覆蓋更強。
?
5. 條件組合覆蓋
含義:使得每個判定表達式中條件的各種可能組合都至少出現一次。
共有8種組合:
???? A>1,B=0 ,?????????????????????? A>1,B≠0
???? A≤1,? B=0,?????????????????????? A≤1,? B≠0.
???? A= 2,?? X>1,?????????????????????? A= 2 ,? X≤1
???? A≠2,?? X>1,????????????????????? A≠2,?? X≤1
測試數據:
??? A=2,B=0,X=4??????? (路徑是:sacbed)
??? A=2,B=1,X=1??????? (路徑是:sabed )
??? A=1,B=0,X=2??????? (路徑是:sabed)
??? A=1,B=1,X=1??????? (路徑是:sabd )
?
??? 滿足條件組合覆蓋標準的測試數據,一定滿足判定覆蓋、條件覆蓋和判定/條件覆蓋標準。
?? 是更強的邏輯覆蓋標準。
?? 但不一定能使程序中的每條路徑都執行到。
???? 如:sacbd
?
6. 點覆蓋
含義:選取足夠多測試數據,使得程序執行路徑至少經過流圖的每個結點一次。
??? 由于流圖的每個結點與一條或多條語句相對應,顯然,點覆蓋標準和語句覆蓋標準是相同的。
?
7. 邊覆蓋
含義:選取足夠多測試數據,使得程序執行路徑至少經過流圖中每條邊一次。
??? 通常邊覆蓋和判定覆蓋是一致的。
?
8. 路徑覆蓋
含義:選取足夠多測試數據,使程序的每條可能路徑都至少執行一次(如果程序圖中有環,則要求每個環至少經過一次)。
? 圖7.5程序有4條可執行通路:
?????? sacbed,sacbd,sabed,sabd.
? 為做到路徑覆蓋,通常需要4組測試數據。
?
?
?
7.6.2? 控制結構測試
?
1. 基本路徑測試
?McCabe提出的一種白盒測試技術;
?可以保證程序中的每條語句至少執行一次;
?每個條件在執行時都將分別取真、假兩種值。
?
使用該技術設計測試用例的步驟如下:
第一步,根據過程設計結果畫出相應的流圖。
流圖
? ?
復合條件的流圖
?
第二步,計算流圖的環形復雜度。
??? 前流圖的環形復雜度為4。
?
第三步,確定線性獨立路徑的基本集合。
??? 每一條新的路徑都包含一條新邊。
??? 程序的環形復雜度決定了程序中獨立路徑的數量。
?
第四步,設計可強制執行基本集合中每條路徑的測試用例。
??? 一旦執行完所有測試用例,就可以確保程序中所有語句都至少被執行了一次,而且每個條件都分別取過true值和false值。
?
?
P156例:測試用PDL描述的求平均值過程。
?首先畫出圖7.6所示的流圖。
PROCEDURE average; /* 這個過程計算不超過100個在規定值域內的有效數字的平均值;同時計算有效數字的總和及個數。*/INTERFACE RETURNS average, total.input, total.valid;INTERFACE ACCEPTS value, minimum, maximum;TYPE value[1…100] IS SCALAR ARRAY;TYPE average, total.input, total.valid;minimum,maximum, sum IS SCALAR;TYPE i IS INTEGER;1: i=1;total.input=total.valid=0;sum=0; 2: DO WHILE value[i] <> -999 3: AND total.input<100 4: increment total.input by1; 5: IF value[i]>=minimum 6: AND value[i]<=maximum 7: THEN increment total.valid by 1;sum=sum+value[i]; 8: ENDIFincrement i by 1; 9: ENDDO 10: IF total.valid>0 11: THEN average=sum/total.valid; 12: ELSE average=-999; 13: ENDIFEND average?
?
圖7.6 求平均值過程的流圖
?
對于圖7.6流圖:
?環形復雜度為6,
?共有6條獨立路徑,P157
?設計執行每條路徑的測試用例。P158
??? 通常在設計測試用例時,識別出判定結點是很有必要的。本例中結點2、3、5、6和10是判定結點。
?
?
7.7? 黑盒測試技術
? 黑盒測試著重測試軟件功能。
? 黑盒測試不能取代白盒測試,是與白盒測試互補的測試方法,用于發現白盒測試不易發現的錯誤。
? 黑盒測試發現的錯誤類型:
? ①功能不正確或遺漏了功能;
? ②界面錯誤;
? ③數據結構錯誤或外部數據庫訪問錯誤;
?④性能錯誤;
? ⑤初始化和終止錯誤。
?
白盒測試主要用于測試過程的早期,
黑盒測試主要用于測試過程的后期。
設計黑盒測試方案時,應該考慮下述問題:
(1) 怎樣測試功能的有效性?
(2) 哪些類型的輸入可構成好測試用例?
(3) 系統是否對特定的輸入值特別敏感?
(4) 怎樣劃定數據類的邊界?
(5) 系統能夠承受什么樣的數據率和數據量?
(6) 數據的特定組合將對系統運行產生什么影響?
?
應用黑盒測試技術,設計測試用例的標準:
(1) 能夠減少為達到合理測試所需要設計的測試用例的總數;
(2) 能夠告訴我們,是否存在某些類型的錯誤,而不是僅僅指出與特定測試相關的錯誤是否存在。
?
黑盒測試技術:
?等價劃分
?邊界值分析
?
7.7.1? 等價劃分
等價劃分:把程序的輸入域劃分成若干個數據類,據此導出測試用例。
??? 一個理想的測試用例能獨自發現一類錯誤。
??? 窮盡的黑盒測試是不現實的。
??? 等價劃分法力圖設計出能發現若干類程序錯誤的測試用例,從而減少必須設計的測試用例的數目。
?等價類:是指某個輸入域的子集合。在該子集合中,各個輸入數據對于揭露程序中的錯誤都是等效的。
?從等價類中選取一個數據進行測試,即可代表整個等價類中所有數據的測試結果,從而減少了測試時間和代價。
? 使用等價劃分法設計測試方案,首先需要劃分輸入數據的等價類。
?
等價類劃分規則:
(1) 如果規定了輸入值的范圍,則可劃分出一個有效的等價類(輸入值在此范圍內),兩個無效的等價類(輸入值小于最小值或大于最大值);
???? ????100 < x < 999
(2) 如果規定了輸入數據的個數,則可劃分出一個有效的等價類和兩個無效的等價類;
(3) 如果規定了輸入數據的一組值,而且程序對不同輸入值做不同處理,則每個允許的輸入值是一個有效的等價類,此外還有一個無效的等價類(任一個不允許的輸入值);
???? X∈{1,3,5,7}
(4) 如果規定了輸入數據必須遵循的規則,則可以劃分出一個有效的等價類(符合規則)和若干個無效的等價類(從各種不同角度違反規則);
(5) 如果規定了輸入數據為整型,則可以劃分出正整數、零和負整數等3個有效類;
(6)如果輸入條件是一個布爾量,則可定義一個有效等價類和一個無效等價類。
?????? X為布爾量
實際情況千變萬化,根本無法一一列出。
?
劃分出等價類以后,根據等價類設計測試方案時主要使用下面兩個步驟:
(1) 設計一個新的測試方案以盡可能多地覆蓋尚未被覆蓋的有效等價類,重復這一步驟直到所有有效等價類都被覆蓋為止;
(2) 設計一個新的測試方案,使它覆蓋一個而且只覆蓋一個尚未被覆蓋的無效等價類,重復這一步驟直到所有無效等價類都被覆蓋為止。
??? 因為程序發現一類錯誤后就不再檢查是否還有其他錯誤,因此,每個測試方案只覆蓋一個無效的等價類。
?
?
下面用等價劃分法設計一個簡單程序的測試方案。
假設有一個把數字串轉變成整數的函數。計算機字長16位,用二進制補碼表示整數。這個函數是用Pascal語言編寫的,它的說明如下:function strtoint (dstr:shortstr):integer;函數的參數類型是shortstr,它的說明是:type shortstr=array[1..6] of char;被處理的數字串是右對齊的,如果數字串比6個字符短,則在它的左邊補空格。如果數字串是負的,則負號和最高位數字緊相鄰(負號在最高位數字左邊一位)。
?
可以劃分出如下等價類:
?
? 有效輸入的等價類有:
(1) 1~6個數字字符組成的數字串(最高位數字不是零);
(2) 最高位數字是零的數字串;
(3) 最高位數字左鄰是負號的數字串;
?
? 無效輸入的等價類有:
(4) 空字符串(全是空格);
(5) 左部填充的字符既不是零也不是空格;
(6) 最高位數字右面由數字和空格混合組成;
(7) 最高位數字右面由數字和其他字符混合組成;
(8) 負號與最高位數字之間有空格;
?
? 合法輸出的等價類有:
(9) 在計算機能表示的最小負整數和零之間的負整數;
(10) 零;
(11) 在零和計算機能表示的最大正整數之間的正整數;
?
? 非法輸出的等價類有
(12) 比計算機能表示的最小負整數還小的負整數;
(13) 比計算機能表示的最大正整數還大的正整數。
??? 因為所用計算機字長16位,能表示的最小負整數是-32 768,能表示的最大正整數是32 767。
?
7.7.2? 邊界值分析
??? 人們從長期的測試工作經驗得知,大量的錯誤是發生在輸入或輸出范圍的邊界上,而不是在輸入范圍的內部。
? 針對各種邊界情況設計測試用例,可以查出更多的錯誤。
? 對等價類方法的補充
?
比如,在做三角形計算時,要輸入三角形的三個邊長:A、B和C。
這三個數值應當滿足:
??? A>0、B>0、C>0、
??? A+B>C、A+C>B、B+C>A,
但如果把 “>”錯寫成 “≥”,那就不能構成三角形。問題恰出現在容易被疏忽的邊界附近。
?
使用邊界值分析方法設計測試方案:
?首先應該確定邊界情況。
?應該選取剛好等于、剛剛小于和剛剛大于邊界值的數據作為測試數據,而不是選取每個等價類內的典型值或任意值作為測試數據。
???????? 100 < x < 999
??? 通常設計測試方案時總是聯合使用等價劃分和邊界值分析兩種技術。
?
7.7.3? 錯誤推測
? 經驗表明,在一段程序中已經發現的錯誤數目往往和尚未發現的錯誤數成正比。
??? 例如,在IBM OS/370操作系統中,用戶發現的全部錯誤的47%只與該系統4%的模塊有關。
??? 因此,要著重測試那些已發現了較多錯誤的程序段。
? 等價劃分法和邊界值分析法都只孤立地考慮各個輸入數據的測試功效,而沒有考慮多個輸入數據的組合效應,可能會遺漏了輸入數據易于出錯的組合情況。
? 選擇輸入組合的一個有效途徑是利用判定表或判定樹為工具,列出輸入數據各種組合與程序應作的動作(及相應的輸出結果)之間的對應關系,然后為判定表的每一列至少設計一個測試用例。
?
7.8? 調試
?調試也稱排錯。
?調試與測試的關系主要體現在以下幾個方面:
? (1)測試的目的是暴露錯誤;而調試的目的是發現錯誤,改正錯誤。
? (2)測試是揭示設計人員的過失,通常應由非設計人員來承擔;而調試是幫助設計人員糾正錯誤,可以由設計人員自己承擔。
? (3)測試發現錯誤后,立即進行調試并改正錯誤,然后進行再測試(回歸測試)。
? (4)調試用例與測試用例可以一致,也可以不一致。
7.8.1? 調試過程
調試總是發生在測試之后,如圖7.8所示。
??? 調試過程從執行一個測試用例開始,評估測試結果,如果發現實際結果與預期結果不一致,表明在軟件中存在隱藏的問題。調試過程試圖找出問題的原因,以便改正錯誤。
調試過程總會有以下兩種結果之一:
?①找到了問題的原因并把問題改正和排除掉了;
?②沒找出問題的原因。此時,調試人員可以猜想一個原因,并設計測試用例附加測試,重復此過程直至找到原因并改正了錯誤。
?
圖7.8 調試過程
7.8.2? 調試途徑
調試的目標:是尋找軟件錯誤的原因并改正錯誤。一般說來,有下列途徑可以采用:
?試探法
?回溯法
?對分查找法
?歸納法
?演繹法
?
1.試探法
? 分析錯誤征兆,猜測發生錯誤的大概位置,然后利用有關的調試技術進一步獲得錯誤信息。這種策略往往是緩慢而低效的。
?
2. 回溯法
?首先檢查錯誤征兆,確定最先發現錯誤的位置,然后人工沿程序的控制流往回追蹤源程序代碼,直到找出錯誤根源或確定故障范圍為止。
?回溯法對于小程序而言是一種比較好的調試策略。但是對于大程序,其回溯的路徑數目會變得很大,以至使徹底回溯成為不可能。
?回溯法的另一種形式是正向追蹤,即使用插入打印語句的方法檢查一系列中間結果,以確定最先出現錯誤的地方。
?
3.對分查找法
? 在程序的中點附近輸入某些變量的正確值(如利用賦值語句或輸入語句),然后觀察程序的輸出。若輸出結果正確,則說明錯誤出現在程序的前半部分;否則,說明程序的后半部分有錯。對于程序中有錯的那部分再重復使用這個方法,直到把錯誤范圍縮小到容易診斷的程度為止。
?
4.歸納法
歸納法:是從個別推斷全體,即從線索(錯誤征兆)出發,通過分析這些線索之間的關系而找出故障。這種方法主要有以下四個步驟:
①收集已有的使程序出錯與不出錯的所有數據。
②整理這些數據,以便發現規律或矛盾。
③提出關于故障的若干假設。
④證明假設的合理性,根據假設排除故障
?
5.演繹法
?演繹法是從一般原理或前提出發,經過刪除和精化的過程,最后推導出結論。
?用演繹法排錯時,首先要列出所有可能造成出錯的原因和假設,然后逐個排除,最后證明剩下的原因確實是錯誤的根源。演繹法排錯主要有以下四個步驟:
??? ①設想所有可能產生錯誤的原因。
??? ②利用已有的數據排除不正確的假設。
??? ③精化剩下的假設。
??? ④證明假設的合理性,根據假設排除故障。
?
7.9? 軟件可靠性 ?
7.9.1? 基本概念
1.? 軟件可靠性的定義
軟件可靠性:是程序在給定的時間間隔內,按照規格說明書的規定成功地運行的概率。
??? 隨著運行時間的增加,運行時出現程序故障的概率也將增加,可靠性隨著給定的時間間隔的加大而減少。
按照IEEE的規定
錯誤:是由開發人員造成的軟件差錯(bug)。
故障:是由錯誤引起的軟件的不正確行為。
?
2. 軟件的可用性
軟件可用性:是程序在給定的時間點,按照規格說明書的規定,成功地運行的概率。
可靠性和可用性之間的主要差別是:
? 可靠性意味著在0到t這段時間間隔內系統沒有失效,
?可用性只意味著在時刻t,系統是正常運行的。
??? 因此,如果在時刻t系統是可用的,則有下述種種可能:
??? 在0到t這段時間內,系統一直沒失效(可靠);
??? 在這段時間內失效了一次,但是又修復了;
??? 在這段時間內失效了兩次修復了兩次;……
?
7.10? 小結
實現包括編碼和測試兩個階段。
??? 編碼是在對軟件進行了總體設計和詳細設計之后進行的,它只不過是把軟件設計的結果翻譯成用某種程序設計語言書寫的程序,因此,程序的質量基本上取決于設計的質量。
??? 但是,編碼使用的語言,特別是寫程序的風格,也對程序質量有相當大的影響。
?
??? 軟件測試仍然是保證軟件可靠性的主要手段。
??? 測試階段的根本任務是發現并改正軟件中的錯誤。
??? 軟件測試是軟件開發過程中最艱巨最繁重的任務,應該分階段地進行,分為單元測試、集成測試和驗收測試3個基本階段。
??? 設計測試方案是測試階段的關鍵技術問題,基本目標是選用最少量的高效測試數據,做到盡可能完善的測試,從而盡可能多地發現軟件中的問題。
??? 兩種測試途徑:計算機進行測試,人工進行測試(例如,代碼審查)。兩種途徑各有優缺點,互相補充,缺一不可。
?
??? 白盒測試和黑盒測試是軟件測試的兩類基本方法,這兩類方法各有所長,相互補充。
??? 在測試過程的早期階段主要使用白盒方法,而在測試過程的后期階段主要使用黑盒方法。
??? 設計白盒測試方案的技術主要有,邏輯覆蓋和控制結構測試;
??? 設計黑盒測試方案的技術主要有,等價劃分、邊界值分析和錯誤推測。
?
??? 在測試過程中發現的軟件錯誤必須及時改正,這就是調試的任務。
??? 為了改正錯誤,首先必須確定錯誤的準確位置,如需要修正原來的設計,必須通盤考慮統籌兼顧,而不能“頭疼醫頭、腳疼醫腳”,應該盡量避免在調試過程中引進新錯誤。
??? 測試和調試是軟件測試階段中的兩個關系非常密切的過程,它們往往交替進行。
?
轉載于:https://www.cnblogs.com/ZanderZhao/p/11094742.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: markdown 中的一些 html 使
- 下一篇: etherum 常用命令及搭建私有链