劉 棟 方麗萍 李國要
(安徽繼遠檢驗檢測技術有限公司,安徽 合肥 230088)
隨著信息化、智能化進程的逐步加深,智能技術逐漸廣泛應用于各類終端設備。嵌入式系統是智能化終端設備的核心,能夠實現設備的自動運行、控制和管理。嵌入式軟件作為嵌入式系統的重要組成部分,也日益受到人們的關注。嵌入式軟件測試在保障終端設備功能完備、可靠穩定上發揮著至關重要的作用。覆蓋率測試是對嵌入式軟件開發設計質量的一種有效衡量手段。一般來說,在用例設計完整的情況下,軟件覆蓋率的高低能夠較好地反映軟件中存在的問題,軟件覆蓋率越高說明軟件程序設計較為完整;軟件覆蓋率低說明軟件程序中存在未被覆蓋的代碼和分支,可以幫助軟件開發設計人員對代碼進行分析,未被覆蓋的代碼是冗余無用的還是由于邏輯缺陷未被執行的,進而有針對性地進行缺陷整改,優化代碼,提升嵌入式軟件的設計質量,也提高了終端產品的可靠性和穩定性。
嵌入式軟件測試一般是指對終端等智能設備中能夠執行某種或某些特定功能的軟件開展功能、性能、接口、邏輯覆蓋等內容的測試。與應用軟件測試存在著一定的差異性,嵌入式軟件的測試與硬件的依賴性較強,不能脫離硬件設備,單獨開展測試[1]。具體存在如下區別:
(1)嵌入式軟件的功能測試與硬件關聯性強,對于軟件、硬件模塊的缺陷定位耗時較長,尤其是對性能的探索性測試需要很大的時間、精力消耗,定位性能的瓶頸比較困難。
(2)嵌入式軟件測試不具有通用性,測試的環境需要指定硬件平臺,并且測試往往發生在宿主機上,受運行環境的影響,因此,嵌入式軟件測試不僅需要在開發環境中開展測試,還要在運行環境中開展測試,這就增加了測試的難度,提高了測試的成本。
(3)嵌入式軟件具有特定性,給嵌入式軟件的自動化測試帶來了技術上的難題。
嵌入式軟件覆蓋率測試是對嵌入式軟件的代碼邏輯和功能結構的正確、適用性進行驗證的必要環節。在進行覆蓋率測試時需要對軟件代碼按照功能模塊進行插樁,并依據相關的設計架構和需求進行用例的設計,用例設計的原則是盡可能覆蓋更多有效的代碼語句、函數、分支條件等,能夠貫穿軟件的內部邏輯結構,只有這樣才可能發現更深層次的代碼設計缺陷和問題[2]。
嵌入式軟件覆蓋率測試一般在單元測試階段進行,通過覆蓋率測試可以檢查出嵌入式軟件代碼是否至少執行一次,也可以發現用例的設計是否完整有效。在測試過程中,要求覆蓋盡可能多的代碼語句、代碼的分支條件和路徑、代碼的重要函數等,保障覆蓋率測試的有效性。嵌入式軟件覆蓋測試主要包括:邏輯分支覆蓋、條件覆蓋測試、語句覆蓋測試、函數的覆蓋測試以及組合覆蓋測試等。
(1)邏輯分支覆蓋:主要是檢查代碼中的所有分支結構是否能夠完全執行。在足夠的用例支撐下,盡可能使得代碼中的每個分支都至少執行一次。在實際測試中,有部分系統的代碼量巨大,要實現代碼的所有分支覆蓋是比較困難的,因此,對于代碼中能夠實現關鍵功能的分支覆蓋率要測試充分,這樣也提高了測試效率。
(2)條件覆蓋測試:主要是代碼中的判斷語句中存在多個條件時,要對每個條件分別設計用例,以滿足執行后可以獲取多個不同的結果。代碼中分支的變化與條件的變化關聯程度較小,所以,條件覆蓋充分還要單獨驗證分支的覆蓋是否充分。為了提高測試的效率,條件覆蓋也是保證代碼的關鍵功能條件覆蓋充分,不造成過多的人力、物力、財力的浪費。
(3)語句覆蓋:語句覆蓋是最基本的覆蓋測試要求,是對代碼中的語句在執行中是否被覆蓋的情況統計。此處的語句指的是代碼中的有效語句,也就是在編譯后,能夠成功執行的語句,不包括代碼的注釋語句和無關語句。語句覆蓋率統計了代碼中的語句在執行中是否至少被執行了一次。單純的語句覆蓋測試不能衡量代碼的質量,因為語句覆蓋不會關心代碼中的分支和條件,有效的代碼覆蓋測試應當結合語句、條件和分支覆蓋,進行綜合評價。
(4)函數覆蓋:函數覆蓋主要是驗證代碼中的各個函數在執行中是否被覆蓋,每個關鍵函數在執行中應該充分覆蓋,避免出現函數未覆蓋而影響代碼的功能執行。關鍵函數的覆蓋對軟件產品的功能有著直接的影響,因此,函數覆蓋也是嵌入式軟件覆蓋測試的重點。
(5)其他覆蓋:其他覆蓋主要是指一些多條件覆蓋以及組合覆蓋[3],至于嵌入式軟件代碼覆蓋率測試中,可依據需求和設計架構,選擇其他或者組合的覆蓋策略,旨在實現代碼覆蓋充分。在面對大量代碼的嵌入式軟件時,代碼的覆蓋充分就是相對的概念,因為還需要考慮測試的效率,避免大量資源的浪費,選擇關鍵的代碼,進行語句、分支、條件、函數等的覆蓋測試,就能夠在一定程度上保障嵌入式軟件的質量和測試的有效性。
嵌入式軟件覆蓋率的計算如下:
其中,嵌入式軟件覆蓋率為C,已執行的語句/分支/函數的代碼的數目為E,代碼中可執行的語句/分支/函數的代碼總數N。
覆蓋率測試是一種在嵌入式軟件在單元測試階段進行的白盒測試,進行覆蓋率測試之前需要依據測試需求和架構說明對用例進行充分設計,設計完成后,對被測代碼程序進行插樁操作,然后通過Gtest編譯生成可執行文件,并運行可執行文件。此時,嵌入式軟件中接口、功能、性能、邊界值、分支條件等項均已執行完成,通過lcov統計覆蓋率數據并寫入文件,最后輸出可視化的覆蓋率報告。嵌入式軟件覆蓋率測試流程如圖1所示。

圖1 嵌入式軟件覆蓋率測試流程圖
嵌入式軟件的代碼覆蓋率測試是對嵌入式軟件的代碼設計有效性的一種評價依據,在用例充分設計的前提下,可以直接展示代碼設計的質量以及各邏輯結構是否設計完全。
目前對于嵌入式軟件的測試工具較多,由于大多數終端設備都是基于C/C++語言進行設計開發的,因此本文選用針對C/C++的測試工具。一些諸如:testbed、c++test等工具的覆蓋率測試是需要付費使用,價格比較昂貴,對于單元和覆蓋率的測試來說,選取一款開源且測試準確率高的工具十分必要。
Gtest是Google提供的開源測試框架,功能強大,測試用例編寫也比較簡化,是一種輕量級的測試工具,可以對嵌入式軟件的功能、接口、變量、邊界值等內容進行驗證,實現嵌入式軟件的單元測試,還可以結合lcov實現軟件代碼覆蓋率的統計,支持語句覆蓋率、函數覆蓋率以及分支覆蓋率的統計;還能提供程序的實際執行信息,包括代碼的執行次數統計,通過html能夠輸出可視化的圖形覆蓋率報告,使用簡單便捷。
在進行嵌入式軟件測試時,測試人員應充分閱讀產品需求說明和架構設計說明,熟悉產品的軟件模塊,以及軟件的功能和運行流程,以便更好地開展測試,設計測試用例,提高測試的效率。
嵌入式軟件的測試環境搭建,需要依賴終端設備。本文搭建的嵌入式軟件測試環境由測試客戶端、終端設備、Xshell工具、keil開發工具、Gtest測試工具、lcov覆蓋率統計工具等要素構成。一般步驟如下:
(1)在測試客戶端中需要安裝Xshell工具,與終端設備建立連接,實現嵌入式軟件代碼的上傳與下載。
(2)安裝keil開發工具,可以實現代碼的編輯、編譯和插樁,為后面覆蓋率的測試提供了前提條件。
(3)在linux系統下,安裝Gtest工具和lcov工具,進行代碼插樁,執行完成后,能夠同時完成單元和覆蓋率的測試,通過查看覆蓋率測試的結果進而對代碼的質量進行評估。
測試用例設計是測試開展的前提條件,只有充分的測試用例設計才會使得覆蓋率結果更為準確,衡量代碼的質量效果更好[4,5]。測試用例設計也就是在測試執行前確定本次測試需要涉及的內容和相關特性要求,提出基本的測試方法。
測試用例設計首先應獲取嵌入式軟件設計的架構和需求,在充分分析設計架構和需求的前提下,研究軟件的功能模塊,并依據模塊,進行用例的設計。用例設計在兼顧代碼重要模塊的同時,還要延伸用例設計的思維,覆蓋正反向用例、邊界用例等。測試用例的基本要素包括:名稱和標識、測試依據、測試的環境要素及要求、測試的輸入輸出、期望結果、結果的評判依據等。
測試用例的設計一般流程如下:
(1)查看嵌入式軟件的設計需求及架構,測試人員應充分了解軟件的模塊及架構,整理軟件的功能模塊,并依據功能模塊設計測試用例。
(2)選取涉及功能模塊的關鍵代碼,加入Gtest相關頭文件,使用工具斷言來實現測試是否符合預期結果。
(3)依次設計好關鍵功能模塊的測試用例,滿足測試的需求。
本文在嵌入式軟件基本測試環境完備情況下,開展覆蓋率測試的一般流程如下:
(1)安裝Xshell工具,運行和配置ip,連接終端設備,通過xftp下載獲取終端設備的嵌入式軟件代碼。
(2)依據產品的需求及架構設計文件,熟悉產品的模塊功能和結構,安裝keil工具,導入源代碼文件,并對應進行編譯和插樁操作。
(3)下載Gtest和lcov安裝包,執行tar命令解壓后進行安裝,安裝完成后查看工具的版本號是否安裝成功。
(4)將插樁后的代碼按照軟件功能模塊,將其劃分為多個后綴為.c/.cpp的文件,并加入測試用例執行腳本后形成待執行文件。
(5)使用Gtest和lcov進行嵌入式軟件的功能和覆蓋率的測試,將待執行的.c/.cpp文件通過Gtest工具編譯,鏈接lGtest庫和lpthread庫,生成可執行文件,執行文件可完成單元測試的結果驗證。
(6)添加-fprofile-arcs和-ftest-coverage參數編譯程序,生成可執行程序和.gcno文件,運行可執行文件,生成.gcda文件,通過lcov收集.gcda文件中的信息,并寫入.info文件,在輸入genhtml指令后生成的一個包含有.html文件的文件夾,其中.html文件即為覆蓋率報告。
測試流程執行完成后,會生成測試結果。執行單元測試功能和接口等測試時,每次執行完成后會出現執行后的結果,若結果中出現報錯信息,顯示期望值與實際值的差異,測試人員可以依據錯誤提示,快速定位失敗信息,并及時修改。若用例測試全部通過,也就說明沒有任何報錯。統計結果一般包括:該用例包括的用例個數、執行通過的測試用例個數、執行失敗的測試用例個數以及失敗用例序號等。執行覆蓋率測試用例后,會生成覆蓋率的結果報告,打開覆蓋率報告,即可查看覆蓋率的統計信息以及詳細的語句覆蓋、分支覆蓋的代碼信息,如圖2所示。

圖2 嵌入式軟件覆蓋率報告結果
可在覆蓋率報告中展開詳細信息,在文件或函數的視圖下,可顯示代碼的具體行數。報告中的代碼前數字表示該語句被執行的次數,代碼語句前的“+”“-”符號,代表分支的個數,其中,“+”號表示該分支在執行中已經被覆蓋,“-”號表示該分支在執行中未被覆蓋,且以紅色標識。
嵌入式軟件覆蓋率報告分別顯示語句覆蓋率、函數覆蓋率、分支覆蓋率的統計結果,代碼中語句、函數、分支已經執行的個數以及總數。在覆蓋率測試結果中,如果出現覆蓋率結果小于100%,則可能出現兩種情況,要分別檢查排除情況。
(1)用例設計不夠充分,可以從測試覆蓋率的結果來檢驗用例的設計,覆蓋率結果中出現某一分支的結果中有標記為“-”,查看對應的分支是否用例已經覆蓋,未發現用例覆蓋,則補充對應用例,再次執行測試,若覆蓋率結果完全覆蓋,則表明用例測試充分,若仍未完全覆蓋,則對應尋找軟件代碼中的設計缺陷問題,記錄缺陷,并與研發人員進行溝通,改進代碼,保障代碼的質量。
(2)代碼本身的質量缺陷,在用例設計充分的前提下,代碼覆蓋率結果仍有未覆蓋,則需尋找代碼的缺陷,該路徑存在執行失敗的問題。
嵌入式軟件覆蓋率測試,可以衡量代碼的質量和用例設計的充分性,在測試人員對用例設計充分的前提下,就能直接反映出代碼本身的質量,對嵌入式軟件的安全可靠提供了保障。
嵌入式軟件在測試中除了關注軟件本身的功能、接口、性能的測試結果,還需要關注軟件的覆蓋率情況,軟件覆蓋率在測試用例充分設計的前提下,可以直接反映出軟件代碼的質量,定位軟件代碼的缺陷問題,也可以幫助測試人員快速查找用例設計的缺失問題,保障用例設計的充分性。因此,嵌入式軟件覆蓋率測試是十分必要的。
本文在充分考慮測試資源的消耗以及測試成本的壓縮上,選用Gtest和lcov完成嵌入式軟件的單元和覆蓋率測試,闡述了嵌入式軟件覆蓋率測試的方法和工具,并對測試的環境搭建、用例設計、詳細流程以及報告分析等方面進行詳細分析,提高了測試人員的測試效率,快速定位缺陷,也幫助研發人員發現嵌入式軟件的設計缺陷,指導進行缺陷的修改,從整體上保障了嵌入式軟件的質量。