198.實現

第7章  實現程序員

 

實現:編碼和測試的統稱。算法

編碼:把軟件設計結果翻譯成用某種程序設計語言書寫的程序。數據庫

 

程序的質量主要取決於:小程序

• 軟件設計的質量。數組

• 所選用的程序設計語言的特色及編碼風格也將對程序的可靠性、可讀性、可測試性和可維護性產生深遠的影響。數據結構

• 軟件測試也是保證軟件質量的關鍵步驟,它是對軟件規格說明、設計和編碼的最後複審。函數

 

 

7.1  編碼  

7.1.1  選擇程序設計語言

• 編碼以前的一項重要工做:工具

     就是選擇一種適當的程序設計語言。佈局

• 高級語言post

    用高級語言寫的程序容易閱讀,容易測試,容易調試,容易維護。

 

選用高級語言的實用標準:

(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有輸入量XY及輸出量Z。在字長爲32位的計算機上運行。若XY取整數,按黑盒方法進行窮舉測試:

 

• 可能採用的

  測試數據組:

    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[1100] 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:    ENDIF
       increment i by 1;
9: ENDDO
10:   IF total.valid>0
11:   THEN average=sum/total.valid;
12:   ELSE average=-999;
13:   ENDIF
      END average

 

 

圖7.6 求平均值過程的流圖

 

對於圖7.6流圖:

•環形複雜度爲6,

•共有6條獨立路徑,P157

•設計執行每條路徑的測試用例。P158

    一般在設計測試用例時,識別出斷定結點是頗有必要的。本例中結點二、三、五、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個基本階段。

    設計測試方案是測試階段的關鍵技術問題,基本目標是選用最少許的高效測試數據,作到儘量完善的測試,從而儘量多地發現軟件中的問題。

    兩種測試途徑:計算機進行測試,人工進行測試(例如,代碼審查)。兩種途徑各有優缺點,互相補充,缺一不可。

 

    白盒測試和黑盒測試是軟件測試的兩類基本方法,這兩類方法各有所長,相互補充。

    在測試過程的早期階段主要使用白盒方法,而在測試過程的後期階段主要使用黑盒方法。

    設計白盒測試方案的技術主要有,邏輯覆蓋和控制結構測試;

    設計黑盒測試方案的技術主要有,等價劃分、邊界值分析和錯誤推測。

 

    在測試過程當中發現的軟件錯誤必須及時改正,這就是調試的任務。

    爲了改正錯誤,首先必須肯定錯誤的準確位置,如須要修正原來的設計,必須通盤考慮統籌兼顧,而不能「頭疼醫頭、腳疼醫腳」,應該儘可能避免在調試過程當中引進新錯誤。

    測試和調試是軟件測試階段中的兩個關係很是密切的過程,它們每每交替進行。

 

 

 

相關文章
相關標籤/搜索