當嵌入式開發(fā)人員測試他們的軟件時,多種力量正在發(fā)揮作用。系統(tǒng)的復雜性越來越大--這是由于對計算工作量的要求越來越大、連通性越來越廣泛以及安全性和可靠性的提高--這使得開發(fā)人員更難根據(jù)需求驗證代碼。隨著發(fā)布時間的縮減,測試團隊很難適應傳統(tǒng)測試方法更大的復雜性和規(guī)模。
需要一種新的測試方法,團隊正在尋找數(shù)學上證明代碼正確性的方法,以顯著提高他們對應用程序的信心。為了理解今天的產(chǎn)品目標和傳統(tǒng)測試方法之間的差距,它有助于考慮復雜性如何影響測試:
· 覆蓋面。 隨著軟件復雜性的增加,創(chuàng)建涵蓋足夠的代碼基礎(包括函數(shù)、語句、路徑、決策和條件)的測試變得越來越難。
· 比例尺。 無論測試范圍--特性、組件、庫或函數(shù)--單位越多,測試它們所需的時間和資源就越多。
· 快一點。 傳統(tǒng)的測試開發(fā)和執(zhí)行實踐無法跟上發(fā)布時間表,不可避免地迫使測試覆蓋率和時間之間的權(quán)衡。
這是一個長期的信念,即接近100%的代碼覆蓋是不可能的,因為這樣的目標非常難以實現(xiàn),運行起來也非常昂貴。單元測試、滲透測試、動態(tài)分析--所有傳統(tǒng)技術(shù)都需要大量的時間和資源來執(zhí)行,并導致系統(tǒng)中錯誤和漏洞的視圖不完整。
隨著最近軟件技術(shù)和計算能力的進步,這種信念現(xiàn)在已成為一個被證實的神話。學術(shù)界和工業(yè)界的研究人員已經(jīng)開發(fā)出了數(shù)學上嚴格的技術(shù),即所謂的正式方法,這些技術(shù)可以達到100%的代碼覆蓋率,并保證系統(tǒng)的正確性--現(xiàn)在可供企業(yè)準備平臺中的安全和安全方面關(guān)鍵的開發(fā)團隊使用。
了解基于正式方法的測試工具
在紙上,正式的方法明確地證明了代碼沒有錯誤和安全漏洞等問題。這些方法使用嚴格指定的數(shù)學模型,根據(jù)精確定義的規(guī)格驗證軟件的特性和行為。換句話說,形式方法可以在代碼中找到所有問題的發(fā)生。
實際上,基于企業(yè)級正式方法的測試工具對任何開發(fā)人員來說都是容易獲得和負擔得起的。被稱為詳盡無遺的靜態(tài)分析工具,它們的設計和證明是為了將正式方法的力量整合到安全和安全關(guān)鍵開發(fā)團隊的現(xiàn)有驗證和驗證過程中。
這些工具與傳統(tǒng)的測試和靜態(tài)分析方法相比有幾個優(yōu)點:
· 高達100%的應用程序覆蓋率,包括所有可能的函數(shù)、語句、路徑、決策和條件。
· 高達100%的輸入覆蓋率,涵蓋測試單元范圍內(nèi)的所有可能值.
· 對代碼中沒有未定義行為(錯誤和漏洞)的數(shù)學保證,導致部署中的零問題。
· 零假底片,所以開發(fā)人員增加了對所有問題都被發(fā)現(xiàn)的信心。
· 低到零的錯誤肯定,意味著開發(fā)人員花在沒有真正問題的問題上的時間較少。
· 大大縮短試驗時間,提高資源消耗效率。
圖1說明了這一差異。傳統(tǒng)的測試方法通常是測試用例開發(fā)和算法設計的"最大努力"嘗試,受到人力和項目進度的限制。這將導致每次運行執(zhí)行一個代碼分支的測試,并限制團隊在給定的測試階段中可以覆蓋多少。在一次測試運行中,在形式方法的支持下,對所有分支進行了詳盡的靜態(tài)分析,將覆蓋率提高到100%,并大大縮短了測試時間。
圖1:傳統(tǒng)測試方法(左)和聲音靜態(tài)分析(右)的代碼路徑比較。被訪問的部分是橙色的;未訪問的部分是黑色的。
充分的靜態(tài)分析可以給開發(fā)人員提供一種強大的管理軟件復雜性的方法,從而極大地改變他們對軟件復雜性的思考方式。
詳盡的靜態(tài)分析
傳統(tǒng)測試方法的一個局限是它們的狀態(tài)空間覆蓋,即對數(shù)據(jù)值和輸入、控制和數(shù)據(jù)流以及它們可以覆蓋的輸出路徑的不同組合數(shù)量的固有限制。例如,傳統(tǒng)的測試方法通常測試預期投入的預期產(chǎn)出的函數(shù)。一些靜態(tài)分析工具擴大了這一范圍,以涵蓋更廣泛的投入和產(chǎn)出。但是由于測試設計、實現(xiàn)和進度限制,工具無法測試所有可能的行為。
下面的代碼示例說明了在數(shù)組中增加單元格值的C函數(shù)。
典型的單元測試將根據(jù)函數(shù)的需求進行驗證,檢查函數(shù)是否增加了輸出數(shù)組中的單元格值,并根據(jù)結(jié)果報告通過或失敗。這個測試不一定會檢查數(shù)組索引(*p)是否由于系統(tǒng)中意外或不希望看到的副作用而導致了對內(nèi)存的越界訪問--就像在這個代碼示例中發(fā)生的那樣,因為當循環(huán)中指定了一個不適當?shù)臈l件。
盡管緩沖區(qū)溢出,傳統(tǒng)的針對需求的測試將在調(diào)用函數(shù)后驗證數(shù)組是{2、4、6、8},并將始終通過,如下控制臺輸出所示:
除非測試設計者考慮到了一個出界數(shù)組訪問的可能性,否則這種緩沖區(qū)溢出將永遠不會被識別。
這些類型的細微缺陷可能會導致內(nèi)存損壞,導致潛在的故障、崩潰或應用程序漏洞--傳統(tǒng)測試方法看不到這種缺陷,但可通過詳盡的靜態(tài)分析工具發(fā)現(xiàn),如圖2所示。該工具檢測到在數(shù)組開始后有一個16字節(jié)的寫入:緩沖區(qū)溢出。
圖2:發(fā)現(xiàn)的屏幕截圖在特魯斯坦軟件詳盡的靜態(tài)分析工具。
這種內(nèi)存損壞可以通過一個更詳細的測試案例來揭示,在這個案例中,出界寫入條件影響變量名稱的值,盡管它不涉及測試的函數(shù),如下表所示:
但是,開發(fā)團隊很少實現(xiàn)這個級別的測試深度,特別是當代碼比這個示例復雜的時候。
硬件意識在靜態(tài)分析中的重要性
更先進的詳盡的靜態(tài)分析工具為驗證和驗證活動帶來硬件意識,從而使測試覆蓋更加準確和高效。硬件意識的重要性怎么強調(diào)都不為過,因為編譯器實現(xiàn)、硬件架構(gòu)和內(nèi)存校準的差異會導致測試條件和代碼行為的巨大差異。例如:
· 在64位目標上,長通常是64位,INT通常是32位。
· 在32位目標上,長和INT通常都是32位。
這些硬件差異影響測試條件、輸入和路徑,如本代碼示例所示:
沒有硬件意識,測試或分析方法將無法確定最后一個語句是否導致整數(shù)溢出(32位目標)或非整數(shù)溢出(64位目標)。在某些情況下,測試將執(zhí)行超出硬件支持的條件所必需的運行。在其他情況下,測試可能會忽略潛在溢出。基于硬件意識的靜態(tài)分析在100%覆蓋率和實現(xiàn)這一目標所需的最小測試用例數(shù)量之間提供了完美的平衡。
另一個關(guān)鍵的硬件差異是整體性,如本代碼示例所示:
根據(jù)底層硬件的整體性,變量C將被設置為0xbe(大Endian)或0xff(小Endy)--這是測試執(zhí)行的一個關(guān)鍵區(qū)別。
這種微妙的差異可能導致災難性的結(jié)果。請考慮在上述代碼示例中添加以下語句的情況:
在一個大的源代碼系統(tǒng)中,這個語句將導致零條件的劃分,并可能導致應用程序崩潰或其他不良行為。在一個小系統(tǒng)上,這個語句是有效的。一個知道這些差異的測試方法會使結(jié)果更精確.
充分的靜態(tài)分析工具,包括硬件意識,也有這些好處:
· 開發(fā)人員可以運行硬件意識分析,而不需要連接到主機的物理目標。
· 目標測試可以在開發(fā)生命周期的早期運行,甚至在物理硬件可用之前。
· 開發(fā)團隊可以通過不需要每個主機和開發(fā)人員的硬件來提高測試能力和降低成本。
詳盡的靜態(tài)分析的未來
嵌入式開發(fā)團隊優(yōu)先進行詳盡無遺的靜態(tài)分析--最高可達100%的代碼覆蓋率和遠遠高于傳統(tǒng)測試的準確性--將從他們的測試投資中獲得最高價值?,F(xiàn)在能夠進入的開發(fā)人員將更有能力提供更高質(zhì)量的代碼,并隨著時間的推移提高測試效率。
從長期來看,從這種嚴格的測試中獲得的結(jié)果和知識將導致"零問題"的保證。這些原則將在開發(fā)過程的早期帶來更強的可測試性,以支持對安全和安保至關(guān)重要的產(chǎn)品要求和設計,并大大降低軟件故障和外地漏洞的可能性。