1. 程式人生 > >前進中的可信計算(Ⅴ):軟體測試

前進中的可信計算(Ⅴ):軟體測試

軟體可靠性牽涉到軟體生產的全過程,但最終還是落實到軟體產品上。而保證軟體可靠性的關鍵步驟是軟體測試。

軟體測試是為了發現故障而執行程式的過程。其目的是以儘可能少的時間和人力發現並改正軟體中潛在的各種故障及缺陷。因此,軟體測試與軟體可靠性緊密相關。軟體中隱藏的故障數目,直接決定軟體的可靠性。所以,在軟體投入執行之前必須進行軟體測試,以儘可能多地發現軟體中的故障,提高軟體可靠性。而在軟體執行過程中,則需要軟體維修測試。

隨著人們對軟體測試重要性認識的加深以及軟體系統的日益複雜,軟體測試在整個軟體開發週期中所佔的比例日益增大。目前,許多軟體開發機構已將研製力量的40%以上花費在軟體測試上。特殊情況下,對於要求高可靠性的軟體,例如飛行控制、核反應堆監控軟體等,其軟體測試費用甚至高達軟體開發其它階段所用費用總和的3-5

倍。

1.軟體測試工程

軟體測試的實質是根據軟體開發各階段的規格說明和程式的內部結構精心選取一批測試資料,形成測試用例,並用這些測試用例去驅動被測程式,觀察程式的執行結果,驗證所得結果與預期結果是否一致,然後做相應的調整。所以,軟體測試本身是一個工程。軟體測試的團隊必須不同於該軟體的設計團隊,它必須獨立地確定軟體測試規範、生成測試資料、進行測試結果分析、寫出測試報告。這一過程可能要反覆進行多次,以達到預定的可靠性。在此過程中,測試資料生成是軟體測試的核心與關鍵。不同測試資料對發現軟體故障的能力差別很大。某些測試資料能夠有效地發現故障,而其他一些測試資料也可能完全是徒勞。為了節約時間和資源,提高測試效率,必須從大量的輸入資料中精心挑選出少數有代表性的測試資料,使得采用這些測試資料能夠達到最佳的測試效果,高效地把隱藏的故障揭露出來。為此,探討如何生成高質高效的測試資料,至關重要。而軟體測試生成與被測軟體的性質、功能和可靠性要求緊密相關。

2.基於程式結構的測試生成

基於規範的功能測試又稱黑盒測試,是以檢查程式功能來檢測程式是否按照規格說明書的規定正確地執行,它以規範說明為依據,選擇和設計測試用例。基於程式的結構測試又稱白盒測試,則根據程式的內部結構設計測試用例,檢測程式在各種不同的情況下是否都按預定的要求正確地執行。基於規範的測試資料生成和基於程式的測試資料生成是兩類常用的軟體測試資料生成方法。

結構測試要求對被測程式的結構特性作到一定程度的覆蓋。覆蓋準則一般有以下幾種:

語句覆蓋

希望用測試資料執行被測程式時,被測程式的每一個語句都能被執行。至少說明每一個語句都是可達的,在該測試條件下,程式是正確的。當然我們並不能保證在其他條件下,程式執行該語句時是否也能正確。

分支覆蓋

If … then … else …語句中,條件語句測試執行一次是不夠的。因為必須讓條件為真和為假,至少執行兩次。而在Case語句中必須執行所有的情況,而且,還要執行不屬於所列情況的default情況。所以,對這些分支語句,必須覆蓋所有可能的分支。分支覆蓋率就是考察測試資料覆蓋了百分之多少的分支。

③路徑覆蓋

由於程式中有分支、迴圈、遞迴、呼叫、跳變等語句,一個程式可以用一個控制流或資料流圖來表示。程式的每一次執行都是沿著某一條路徑走的。程式在執行這些測試資料時,沿著許多路徑都執行過。如果能沿著所有路徑都執行一遍,當然很好。如果能做到完全的路徑覆蓋,就必然達到100%的分支覆蓋和語句覆蓋。但是,對於較大的程式,基本上不可能沿著所有路徑都執行一遍,因為路徑數太多了。執行過的路徑數對所有路徑數的百分比就是路徑覆蓋率。

測試資料生成的過程就是在輸入域中,尋找滿足測試準則(如語句覆蓋、分支覆蓋或路徑覆蓋)的輸入資料的過程。

關於結構測試,有三種測試資料生成方法:隨機測試資料生成方法、面向目標的測試資料生成方法以及面向路徑的測試資料生成方法。

n對於給定的語句(分支或路徑),隨機測試資料生成方法是在輸入域內隨機選取測試資料,使得給定語句被執行。

n面向目標的測試資料生成方法,依據程式控制流資訊,將程式中所有的分支分成兩類:一類是影響目標結點的分支,另一類是不影響目標結點的分支。測試資料生成時,根據影響目標結點的那些分支,生成相應的測試資料,使得給定語句被執行。為了能按照預定的分支,走向給定語句,資料依賴分析是必要的。分析資料依賴關係,識別影響給定語句執行的那些語句,即先於給定結點執行的結點序列,再考慮影響目標結點的那些分支,可以提高測試資料生成效率。面向目標的測試資料生成方法,與路徑選擇無關,雖然可以達到語句覆蓋、分支覆蓋,但在結構測試覆蓋準則中,路徑覆蓋率是較低的,只有當程式中每一條路徑都被測試了,才能說程式得到了全面的檢驗。

n面向路徑的測試資料生成方法,首先確定一條經過給定語句的程式路徑,這條路徑可以自動生成,也可以人為指定。然後在輸入域中尋找輸入資料,使得在此輸入之下,程式沿該路徑執行,從而使得給定語句被執行。面向路徑的測試資料生成又分為符號執行和實際程式執行兩類。符號執行允許程式輸入常量、符號值、符號表達式等,以符號計算代替實際執行的數值計算,產生一個符號輸入值的代數表示式,即路徑約束,它是選定路徑的謂詞系統。實際上是對輸入資料的限制要求,由多個不等式(等式)組成。通過求解不等式,求取滿足路徑上各限制謂詞的測試資料。若系統無解,則相應的路徑為不可行路徑。與邏輯電路測試類似,軟體測試也可以基於故障來產生。用代數約束來描述檢測特定型別故障的測試資料。符號執行能夠判定路徑的可行性,一次符號測試的結果代表了一類普通測試的執行結果,因此測試成本較低。但在遇到迴圈、過程呼叫、動態資料結構、陣列和指標處理時,符號執行實現困難。基於程式實際執行的測試資料生成方法可以對選定路徑上的分支謂詞,寫出一個邏輯表示式,再進行布林函式極小化,以確定輸入資料,使程式執行沿選定路徑進行。也可以利用迭代逼近法,求取滿足選定路徑上所有謂詞的輸入值。每次迭代中,執行與選定路徑謂詞有關的語句,得到一個線性約束集,求解該線性約束集,獲得一個輸入增量,進而得到下次迭代的輸入值,最終產生選定路徑的測試資料。也可以用約束求解的方法生成測試資料,將被測程式轉化成一個約束系統,然後尋找經過給定語句的路徑,生成相應的測試資料。基於程式實際執行的測試資料生成方法,在程式執行的每一步,陣列下標、指標值都是確定的。因此,對陣列和指標的處理方便,但其測試資料生成與路徑選擇有關,而判定所選路徑是否為可行路徑是一件非常困難的事情。

隨機測試資料生成、面向目標的測試資料生成和麵向路徑的測試資料生成方法大多隻利用控制流資訊生成測試資料。而利用資料流資訊生成測試則是另一類測試生成方法。該方法將資料流資訊應用到路徑選擇中,並定義了相應的測試覆蓋準則。例如,所有定義引用路徑覆蓋準則是指在一個變數被定義之後,所有引用該變數的語句都必須被覆蓋。而所有定義覆蓋準則則要求所有定義變數的語句都必須被覆蓋。所有計算引用覆蓋準則要求所有計算出來的變數被引用的通路都必須被覆蓋。資料流測試已經開發了一些軟體測試工具,例如ATAC,能夠評估測試集的覆蓋率,識別未被覆蓋的程式範圍等,有利於指導選擇測試用例,提高測試覆蓋率。但是,無論哪一種結構測試,即使其覆蓋率達到百分之百,也不能保證把所有隱藏的程式缺陷都揭露出來。

3.面向物件軟體的測試

面向物件的方法(Object-oriented method, OO)是軟體工程方法的一次飛躍。物件是一個具有一組狀態的實體,並封裝了附加於這些狀態的操作。狀態描述了物件的屬性或特徵,操作描述了物件改變其狀態的方法以及該物件為其他物件所提供的服務。面向物件方法認為,人類生活在一個由物件組成的世界中。物件可以被歸類、描述、組織、組合、建立和操縱。面向物件方法是一種模型化世界的抽象方法,結構上具有良好的高內聚低耦合特性。採用面向物件技術設計和開發的軟體系統更易於維護,在對系統進行修改時,能夠產生較少的副作用。同時,面向物件技術提出了類、繼承、介面等概念,從而為物件的複用提供了良好的支援機制。因而採用面向物件技術對軟體產品進行設計與開發,能夠有效地提高軟體組織的開發效率。

隨著面向物件分析和麵向物件設計技術的日漸成熟,面向物件的軟體開發技術得到了軟體界的普遍認可。但是,由於面向物件的程式設計語言提供了資料抽象、繼承、多型和動態繫結等機制,傳統的軟體測試方法以及測試工具已不能為面向物件的軟體提供良好的支援。

面向物件的程式中,物件是封裝了描述其屬性的資料及可以施加在這些資料上的操作的封裝體。屬性表示物件的狀態,操作表示物件的行為,訊息描述了物件執行操作的規格說明。物件之間通過傳送訊息啟動相應的操作,通過修改物件的狀態,實現系統狀態間的相互轉換。類是對具有相同屬性和行為的一組相似物件的描述,它描述了該類物件所具有的共同特徵。面向物件軟體的測試與傳統的軟體測試有所不同。從面向物件單元測試開始,要考慮類間的繼承測試。可以根據類間繼承關係的層次特性對類進行增量測試,即通過複用和增量更新父類的測試資訊去指導子類的測試。有人根據類是抽象資料型別的實現這一原理,引入了一種和麵向物件語言語法相似的代數規範描述語言LOBAS,作為類的測試模型。通過分析軟體的需求和功能規範來選擇和產生測試資料,重點測試一個作用於被測類物件的訊息序列能否使該物件處於正確的狀態。也可以採用黑盒測試和白盒測試相結合的方法,用黑盒測試法選取測試用例,用白盒測試來檢測程式執行一個測試用例產生的兩個物件是否觀測等價(即處於相同的抽象狀態),並補充一些測試用例,對類進行測試。

對傳統軟體,測試人員普遍認為可以分為四個級別的測試:單元測試、整合測試、確認測試和系統測試。面向物件的程式測試應當分為幾個級別,目前尚未達成共識。一種意見認為,從面向物件程式的結構出發,面向物件的程式測試應當分為四個級別:

1). 行為級:測試類中定義的每個操作;

2). 類級:測試封裝在一個類中的操作和資料之間的相互作用;

3). 簇級:測試一組協同工作的類之間的相互作用;

4). 系統級:考察由所有類和主程式構成的整個系統。

而另一種意見則認為面向物件的程式執行實際上是執行一個由外部事件驅動的操作序列。根據這一特徵,應將面向物件的測試分為五個層次:

1). 行為測試;

2). 訊息路徑測試;

3). 系統基本功能測試;

4). 執行緒測試;

5). 執行緒間相互作用測試。

繼承是指子類自動共享父類中定義的資料和操作的機制,多型是指當同一個訊息被不同的物件接受時,可以導致完全不同的行為。繼承與多型機制,是面向物件程式實現重用的主要手段,同時也給面向物件軟體的測試提出了一些新的問題。目前關於面向物件軟體測試的研究,大多集中在類和物件狀態的測試方面。雖有文獻提及繼承及動態繫結對軟體測試的影響,但現有的面向物件軟體測試方法大都忽略了動態繫結的作用和影響,而且尚無普遍接受的面向物件軟體測試的充分性準則。對這些問題的深入研究將會對軟體測試的理論與實踐起到積極的指導作用。

4.軟體測試工具

為了提高軟體測試效率,加快軟體開發過程,許多公司和大學、科研機構開發了軟體測試工具。我國在軟體測試工具研發方面也做了大量工作。它們大致可分為靜態分析工具、測試資料生成工具、測試評估工具以及將多種測試工具融為一體的整合化測試系統等。

·靜態分析工具

靜態分析工具是在不執行程式的情況下,分析軟體的特性。靜態分析主要集中在需求文件、設計文件以及程式結構上,可以進行型別分析、介面分析、輸入輸出規格說明分析等。

·測試資料生成工具

測試資料生成工具可以為被測程式自動生成測試資料,減輕人們在生成大量測試資料時付出的勞動,同時還可避免測試人員對一部分測試資料的偏見。

·測試評估工具

測試評估工具用來評估程式結構元素被覆蓋的程度,從而確定測試執行的充分性。這是使用測試資料生成工具生成測試資料之後必須使用的工具。

·整合化測試系統

整合化測試系統將多種測試工具融為一體,是一種功能較強的測試工具。

一般地說,針對一類特定軟體的測試工具,可以是相當有效的。而要想開發對所有軟體系統都有效的軟體測試工具,幾乎是不可能的。並且,經驗表明,走查,即由測試工程師認真閱讀源程式以發現錯誤,仍不失為一種靠得住的測試方法,雖然這不屬於自動測試方法。

5.程式切片技術

對於大型的複雜軟體系統的測試,應該提到程式切片技術。它是一種分析和理解程式的技術,廣泛應用於程式除錯、測試、逆向工程及軟體維護中。它以切片標準為準則,從被測程式中抽取滿足切片標準要求的有關語句,忽略許多與此無關的語句,有利於故障原因的定位分析。

程式切片是一個可執行的程式部分,由可能影響程式某個興趣點處變數值的所有語句和謂片語成。

程式切片分為靜態切片和動態切片。

靜態切片考慮了程式所有可能的執行路徑。通過分析源程式程式碼,獲得有關資訊,可以計算程式的靜態切片。對於程式的某個變數而言,靜態切片計算出的該變數值與源程式計算出的該變數值在任何輸入下都是相同的。

動態切片只考慮某個具體輸入下程式的執行路徑,由路徑上影響或間接影響程式某個興趣點處變數值的所有語句和謂片語成。根據實際輸入執行產生的精確資料流資訊,即在特定執行過程中產生的資料依賴,計算程式的動態切片。