林廣棟 耿銳 趙香
摘要:覆蓋率統(tǒng)計是軟件白盒測試的重要手段。BWDSP處理器為其軟件用戶實現(xiàn)了一個代碼覆蓋率統(tǒng)計工具。該工具可以統(tǒng)計語句覆蓋率、分支覆蓋率,還可以用累加方式統(tǒng)計覆蓋率。該工具通過調(diào)試信息得到被測軟件的代碼行號信息。它使被測軟件在BWDSP模擬器上運行,并同時搜集被測軟件的覆蓋信息,最后把覆蓋信息與行號信息結(jié)合得到覆蓋率。該覆蓋率統(tǒng)計工具已經(jīng)被BWDSP操作系統(tǒng)等大型軟件在測試時使用,對這些軟件的測試工作起到了重要作用。
關(guān)鍵詞:軟件測試;覆蓋率;BWDSP
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2016)05-0066-05
Abstract: Coverage testing is an important test mothed for whilte-box testing.A coverage testing tool for BWDSP software is developed. The tool can generate statement coverage rate, branch coverage rate, and can accumulatively generate coverage rate. It get line number information from debug information. It runs the software for testing in BWDSP simulator, and collects coverage information at the same time. It combines line number information and coverage information to get coverage rate. The tool has been used in testing BWDSP operating system, and played an important role in the testing.
Key words: software test; coverage rate; BWDSP
軟件測試指用人工或自動的手段對軟件進(jìn)行運行或試驗的過程,目的是檢驗軟件是否滿足規(guī)定的需求。軟件測試不僅要找出錯誤,還要找出錯誤所在位置。隨著軟件復(fù)雜程度的日益增加,軟件測試變得越來越重要[1-2]。一般,軟件測試應(yīng)占軟件開發(fā)整個過程的40%以上。在某些對可靠性要求高的領(lǐng)域,如航天、金融領(lǐng)域,軟件測試所占的時間更長。
如果一段代碼在測試過程中沒有被運行到,那就無法確保這段代碼是正確的。如果一個條件判斷語句的某一種條件在測試過程中從未被滿足,那就無法確保該條件滿足時軟件是正確的。覆蓋率測試就是一種針對軟件代碼和分支是否被覆蓋而設(shè)計的一種測試方法,是軟件測試的一種重要手段。它需要得到被測軟件的源代碼,是一種白盒測試方法。覆蓋測試包括語句覆蓋、條件覆蓋、分支覆蓋、條件組合覆蓋、路徑覆蓋等等。語句覆蓋測試統(tǒng)計源代碼中每條語句是否被運行。測試過程中已經(jīng)運行的語句行數(shù)和全部語句行數(shù)的比率稱為軟件測試的語句覆蓋率。顯然,軟件測試的語句覆蓋率越高,軟件測試就越充分。條件覆蓋測試檢查軟件代碼中條件結(jié)果的覆蓋情況,目的是使源代碼中每個條件取得所有可能的值。分支覆蓋測試檢查每個分支處的可能跳轉(zhuǎn)的覆蓋情況。條件組合覆蓋測試檢查源代碼分支判斷中各個條件的所有可能組合的覆蓋情況。路徑覆蓋測試檢查測試過程對軟件執(zhí)行流程中所有可能的路徑的覆蓋情況。理想的測試方案應(yīng)使以上所有種類的覆蓋率都達(dá)到100%。但是為了實現(xiàn)這個目標(biāo)需要設(shè)計大量測試用例,代價非常高。一般情況下,只需要覆蓋率滿足一定條件即可。無論如何,覆蓋率測試作為一種有用的信息,可以對設(shè)計有效的測試用例進(jìn)行指導(dǎo)。
統(tǒng)計被測軟件的覆蓋率一般分為兩類方法。第一類方法適用于運行于主機(jī)上的通用軟件。這類方法把被測軟件的行號、條件、分支等信息記錄下來,并在被測程序的源代碼中需要統(tǒng)計覆蓋率的位置插入記錄覆蓋率的代碼(這個過程稱為“插樁”)。被測軟件執(zhí)行時,這些插樁的代碼也會執(zhí)行,并把覆蓋信息記錄下來。執(zhí)行完畢后,再把覆蓋信息與被測軟件的行號、條件、分支等信息結(jié)合,得到被測軟件的覆蓋率信息[3-5]。第二類方法適用于嵌入式系統(tǒng)。這類方法同樣要執(zhí)行插樁過程。不同的是,由于被測軟件運行于嵌入式系統(tǒng)上,覆蓋信息需要通過網(wǎng)線、串口線等物理介質(zhì)發(fā)送給主機(jī)。測試用例執(zhí)行完畢后,在主機(jī)上統(tǒng)計分析得到覆蓋率信息。第二類方法往往需要覆蓋率統(tǒng)計軟件提供插樁、通信、統(tǒng)計等一整套工具[6-14]。
常見的覆蓋率統(tǒng)計工具包括gcov、Magellan[5]、Logiscope[6]、Bullseye[3,7]、CutteleITE[9]、Testbed[10]等等。gcov是一款Linux系統(tǒng)自帶的與gcc協(xié)同工作的覆蓋率測試工具。使用gcov時,需要要在編譯程序時在gcc后加上特定的編譯選項。gcc會自動在編譯生成的可執(zhí)行文件的特定位置插入特定代碼,并把源代碼的行號、分支等信息儲存在一個特殊的文件中。當(dāng)程序執(zhí)行時,這些插入的代碼一并執(zhí)行,把覆蓋信息記錄下來。最后調(diào)用gcov命令,gcov會結(jié)合被測程序?qū)嶋H執(zhí)行中的覆蓋信息與源代碼信息,給出其測試過程中的覆蓋率信息。Bullseye工作原理與gcov類似,不同的是,它是在源代碼級別上向被測軟件中插入記錄覆蓋率信息的代碼,然后調(diào)用一般的編譯器進(jìn)行編譯。它既可以在Linux系統(tǒng)下工作,也可以在windows環(huán)境下工作,而且支持多種編譯器。Logiscope支持對嵌入式軟件的覆蓋率測試。它提供了運行于目標(biāo)機(jī)操作系統(tǒng)上的收集覆蓋信息并與主機(jī)進(jìn)行通信的軟件包。用戶需要在主機(jī)端使用Logiscope向被測程序中插入代碼。被測軟件在嵌入式目標(biāo)機(jī)上執(zhí)行時,把覆蓋信息通過特定物理通道(如網(wǎng)線、串口線)發(fā)送給主機(jī)。被測軟件執(zhí)行完后,在主機(jī)端通過Logiscope事后分析工具得到被測軟件的覆蓋率信息。
BWDSP是一款我國自主研發(fā)的高性能DSP,其配套的基礎(chǔ)軟件也是自主研發(fā)的[15-16]。隨著BWDSP芯片的應(yīng)用領(lǐng)域越來越廣泛,基于BWDSP芯片開發(fā)的軟件也變得更加復(fù)雜,也需要進(jìn)行覆蓋率測試。因此,必須開發(fā)BWDSP配套的覆蓋率統(tǒng)計工具。BWCoverageTest是一款借鑒其他覆蓋率統(tǒng)計工具自主研發(fā)的覆蓋率統(tǒng)計工具,既支持統(tǒng)計C程序的覆蓋率,也支持統(tǒng)計匯編程序的覆蓋率。BWCoverageTest可以統(tǒng)計被測軟件的語句覆蓋率和分支覆蓋率,并支持以累加方式統(tǒng)計覆蓋率。本文將對BWCoverageTest的使用方法、實現(xiàn)原理、算法流程、下一步工作等內(nèi)容進(jìn)行介紹。
1 簡介
BWDSP是一款國內(nèi)自主研發(fā)的數(shù)字信號處理器(DSP),屬于嵌入式芯片。在BWDSP上運行的軟件也屬于嵌入式軟件。這些軟件需要在主機(jī)上進(jìn)行編譯,生成可執(zhí)行文件,然后通過某種物理介質(zhì)加載到處理器中運行。進(jìn)行覆蓋率測試必須要運行被測軟件。如果被測軟件屬于嵌入式軟件,則只能使用前述第二種方法,使被測軟件的覆蓋信息通過某種物理介質(zhì)發(fā)送到主機(jī)上。這種測試方法需要有實際的板卡和物理介質(zhì),代價較大。通過這種方法開發(fā)的覆蓋率統(tǒng)計工具一般也比較復(fù)雜。BWDSP處理器配套有一個成熟的周期精確的芯片模擬器。可以通過使被測軟件在該芯片模擬器上運行,直接在主機(jī)上收集覆蓋信息。這種方法對硬件環(huán)境要求不高,且簡單易用、測試速度較快。利用這種方法開發(fā)的覆蓋率統(tǒng)計工具功能相對比較單純,易于實現(xiàn)。
BWCoverageTest基于一個定制的BWDSP芯片模擬器(BWSimulator)實現(xiàn)。BWCoverageTest的工作過程分為兩步。第一步調(diào)用BWSimulator執(zhí)行被測軟件,直到被測軟件運行結(jié)束。BWSimulator記錄下程序運行過程中每個程序地址(PC)上經(jīng)歷的次數(shù)。BWSimulator內(nèi)部分析匯編指令,判斷是否為分支指令,并把分支所在程序地址、進(jìn)行跳轉(zhuǎn)的方向等信息記錄下來。BWCoverageTest的第二步是結(jié)合被測程序的行號信息和BWSimulator生成的覆蓋記錄,分析得到被測軟件的語句覆蓋率和分支覆蓋率,并給出未覆蓋到語句和分支。BWCoverageTest工具的整體工作過程如圖1所示。目前,BWCoverageTest只能統(tǒng)計語句覆蓋率和分支覆蓋率。
2 使用方法
BWCoverageTest有兩種使用方式:非累加方式和累加方式。以非累加方式使用時,只統(tǒng)計本次測試的覆蓋率;以累加方式使用時,把過去所有以累加方式測試的覆蓋情況累加起來統(tǒng)計覆蓋率。對于復(fù)雜的軟件,一個測試用例很難也沒有必要覆蓋所有的代碼。一般把被測軟件劃分為若干模塊,每個測試用例測試其中一個或若干個模塊。最終測試的目的是使這些測試用例全部運行后覆蓋到盡可能多的語句或分支。顯然,單純統(tǒng)計一次測試過程中覆蓋率的工具已經(jīng)不滿足要求,要求覆蓋率測試工具提供累加測試功能。
2.1 非累加方式
需要以累加方式統(tǒng)計代碼覆蓋率的代碼不能位于main.c文件中和app文件夾中,且每次累加統(tǒng)計時不能改變被測部分的代碼。例如,有a.c、b.c兩個.c文件中的代碼需要以累加方式統(tǒng)計代碼覆蓋率,可以在main.c中調(diào)用a.c和b.c中的函數(shù),或在app文件夾中建立源文件,調(diào)用a.c和b.c中的函數(shù)。且每次進(jìn)行累加統(tǒng)計時,a.c和b.c中的代碼不能改變。因為若代碼改變,則無法準(zhǔn)確判斷一行代碼是否被覆蓋到。被測試文件在不同統(tǒng)計過程中可以位于不同的代碼段,甚至不必在每次累加測試時都鏈接到工程中。例如:第一次統(tǒng)計過程中可執(zhí)行文件中包含a.c中的代碼,第二次統(tǒng)計過程可執(zhí)行文件中包含b.c中的代碼,累加統(tǒng)計時,會統(tǒng)計a.c和b.c總體的覆蓋率。
3 軟件模擬器
BWDSP芯片配套有周期精確的軟件模擬器。該模擬器用C++語言基于SystemC庫開發(fā)。BWSimulator是一個專為統(tǒng)計覆蓋率而設(shè)計的軟件模擬器,在普通BWDSP軟件模擬器基礎(chǔ)上增加了記錄程序地址和分支判斷結(jié)果的功能。
被測軟件運行結(jié)束后,m_cond_pc中所有關(guān)鍵字即是被測軟件所經(jīng)歷的分支地址,該關(guān)鍵字對應(yīng)的鍵值記錄了在該分支處進(jìn)行跳轉(zhuǎn)和不進(jìn)行跳轉(zhuǎn)的次數(shù)。其中cnttrue記錄進(jìn)行跳轉(zhuǎn)的次數(shù),cntfalse記錄不進(jìn)行跳轉(zhuǎn)的次數(shù)。
4行號信息分析
BWCoverageTest使用被測文件的調(diào)試信息得到其程序地址和行號信息的對應(yīng)關(guān)系[18]。BWCoverageTest利用BWDSP調(diào)試系統(tǒng)中分析行號調(diào)試信息的模塊,同時支持對STABS格式和DWARF格式調(diào)試信息的分析。
5 算法
5.1 非累加方式
以非累加方式統(tǒng)計覆蓋率時,BWCoverageTest將被測文件調(diào)試信息中存儲的程序地址構(gòu)成一個STL關(guān)聯(lián)容器set(集合),記為AllSet。該集合為被測軟件可能經(jīng)過的需要進(jìn)行統(tǒng)計的程序地址集。以BWSimulator實際執(zhí)行過程中記錄的程序地址構(gòu)成一個集合,記為RunTimeSet。
被測軟件會包含一些C語言標(biāo)準(zhǔn)庫,這些庫不帶調(diào)試信息,也不需要統(tǒng)計覆蓋率,但在實際執(zhí)行過程中會執(zhí)行到。這些庫執(zhí)行過程中經(jīng)過的程序地址會出現(xiàn)在RunTimeSet中,但不會出現(xiàn)在AllSet中。在統(tǒng)計C語言程序的覆蓋率時,AllSet中記錄的是被測軟件每一行C語言代碼的程序地址,而一行C語言代碼會被編譯成為多行匯編代碼。這些匯編代碼行的程序地址都可能出現(xiàn)在RunTimeSet中。所以RunTimeSet中包含很多AllSet中不包含的程序地址,RunTimeSet并不是AllSet的子集。
RunTimeSet與AllSet的合集,就是被測軟件執(zhí)行過程中執(zhí)行到的代碼行的程序地址集。顯然,該合集的大小與AllSet集合的大小的比率,就是被測軟件的代碼覆蓋率。而AllSet與RunTimeSet的差集,就是未被覆蓋到的代碼行。
BWCoverageTest統(tǒng)計分支覆蓋率的方式較為簡單,將分支跳轉(zhuǎn)記錄中兩種跳轉(zhuǎn)數(shù)都不為0的分支數(shù),除以該分支跳轉(zhuǎn)記錄中的總分支數(shù),即為分支覆蓋率。如果一個分支從未被執(zhí)行,那BWSimulator也不會記錄該分支的跳轉(zhuǎn)記錄。只有當(dāng)語句覆蓋率為100%時,BWCoverageTest得到的分支覆蓋率才準(zhǔn)確。當(dāng)語句覆蓋率小于100%時,只有通過編譯器記錄下全部分支的程序地址,才有可能準(zhǔn)確得到哪些分支未被覆蓋到,此時得到的分支覆蓋率才是準(zhǔn)確的分支覆蓋率。這也是BWCoverageTest下一步的工作方向。
5.2 累加方式
對累加方式進(jìn)行覆蓋率統(tǒng)計的需求來源于對BWDSP操作系統(tǒng)的測試。BWDSP操作系統(tǒng)為應(yīng)用程序提供一組API,應(yīng)用程序通過調(diào)用這些API來使用操作系統(tǒng),應(yīng)用程序本身就相當(dāng)于測試用例。但應(yīng)用程序和BWDSP操作系統(tǒng)都會被編譯到同一個可執(zhí)行文件中。一般很難在一個應(yīng)用程序中調(diào)用所有BWDSP操作系統(tǒng)的API,所以很難用一個應(yīng)用程序使BWDSP操作系統(tǒng)的語句覆蓋率達(dá)到規(guī)定的要求。而以累加方式統(tǒng)計時,測試人員可以使用多個應(yīng)用程序,分次進(jìn)行覆蓋率測試。每個應(yīng)用程序測試操作系統(tǒng)的一個功能或一個模塊。每次測試時,甚至可以把本次測試不需要的操作系統(tǒng)源代碼文件從軟件工程中排除。唯一的要求是操作系統(tǒng)的代碼不能改變。
BWCoverageTest規(guī)定,應(yīng)用程序可以位于main.c源文件中,或位于app文件夾下。以累加方式進(jìn)行覆蓋率統(tǒng)計時,對這兩個位置的源代碼行,不再進(jìn)行統(tǒng)計。BWCoverageTest以累加方式進(jìn)行測試時,還可以統(tǒng)計每個文件的累加覆蓋率。
累加方式對每次測試時被測源代碼文件是否全部被包含不作要求,因此源代碼中的一行在每次測試時對應(yīng)的程序地址不同。所以不能再利用程序地址是否被經(jīng)過作為覆蓋率統(tǒng)計的依據(jù)。累加方式統(tǒng)計累加覆蓋率的依據(jù)是每個源文件中一行代碼是否被覆蓋到。
RunFileLine也是map數(shù)據(jù)結(jié)構(gòu),關(guān)鍵字為源文件名,而鍵值則是累加測試過程中經(jīng)歷的程序地址對應(yīng)的行號。
根據(jù)BWSimulator一次測試過程中記錄下來的程序地址記錄,以及該次測試過程中可執(zhí)行文件中的調(diào)試信息,分析得到源文件中的某個行號在本次測試中是否被覆蓋。若被覆蓋,則加入到RunFileLine數(shù)據(jù)結(jié)構(gòu)中。
其中tdi是一個分析可執(zhí)行文件中行號信息的C++類的實例。累加測試過程中,由于每次測試時被測軟件在可執(zhí)行文件中的位置不一定相同,每分析一次測試過程產(chǎn)生的記錄信息,tdi都要重新分析一次該次測試過程中的可執(zhí)行文件。
最后,以覆蓋到的行號數(shù)量除以全部源文件的行號數(shù)量,即是被測軟件的累加覆蓋率。累加方式覆蓋率統(tǒng)計的流程如圖3所示。
6 下一步工作
BWCoverageTest目前已經(jīng)可以進(jìn)行語句覆蓋率和分支覆蓋率測試,但仍存在一些不足。下一步工作計劃如下:
1) 支持準(zhǔn)確分析分支覆蓋率。利用編譯器得到被測軟件分支的程序地址記錄。即使語句覆蓋率達(dá)不到100%,分支覆蓋率也是準(zhǔn)確的。
2) 支持分析條件覆蓋率。借助于編譯器得到生成條件結(jié)果時的程序地址,并得到條件結(jié)果(“真”或“假”)存儲的位置。這種條件結(jié)果一般應(yīng)存放于某個寄存器中。BWSimulator在生成該條件結(jié)果時通過結(jié)果所在位置得到條件結(jié)果實際取值,再記錄下來。BWCoverageTest借助BWSimulator生成的條件覆蓋信息得到條件覆蓋率。
3) 支持分析條件組合覆蓋率。借助于編譯器得到生成分支判斷結(jié)果時的程序地址,以及生成條件結(jié)果時的程序地址。BWSimulator記錄下分支判斷取真或假的結(jié)果,以及條件的結(jié)果。最后由BWCoverageTest分析得到分析條件組合覆蓋率。
4) 集成到開發(fā)環(huán)境。目前BWCoverageTest以命令行的方式使用,對用戶不太友好。下一步應(yīng)考慮將BWCoverageTest集成進(jìn)行BWDSP集成開發(fā)環(huán)境,成為該軟件的一個附屬工具。并以圖形界面的方式把語句覆蓋率、分支覆蓋率等結(jié)果顯示出來。
7 總結(jié)
BWCoverageTest是一個自主創(chuàng)新實現(xiàn)的覆蓋率測試工作,可以測試BWDSP處理器上的軟件覆蓋率。BWCoverageTest使用軟件模擬器記錄被測軟件的運行信息,結(jié)合被測軟件的行號信息,得到覆蓋率信息。BWCoverageTest還支持以累加方式使用,使多次統(tǒng)計過程的覆蓋情況可以累加。但BWCoverageTest仍存在很多不足之外。它不能統(tǒng)計條件覆蓋率、條件組合覆蓋率等更高級的覆蓋率信息。這些都是BWCoverageTest下一步研究的方向。
參考文獻(xiàn):
[1] Paul C Jorgensen. Software Testing: A Craftsmans Approach[M]. 2nd ed. USA:CRC Press, 2002.
[2] Robert Culbertson, Chris Brown, Gary Cobb. RAPID Testing[M]. USA: Posts and Telecom Press, 2002.
[3] 顧惟祎.基于代碼覆蓋統(tǒng)計的BMC回歸測試用例選擇系統(tǒng)的設(shè)計與實現(xiàn)[D].南京:南京大學(xué),2013.
[4] 李列鋒.基于二進(jìn)制可執(zhí)行文件代碼覆蓋測試技術(shù)研究[D].鄭州:解放軍信息工程大學(xué),2007.
[5] 胡飛,朱佳.用Magellan測試代碼覆蓋率[J].科學(xué)技術(shù)與工程,2006,6(12),1710-1712.
[6] 陳麗蓉,熊光澤,羅蕾,等.嵌入式軟件的覆蓋測試[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2002,2(11):8-11.
[7] 蘇華龍,陸松年.代碼覆蓋分析工具在嵌入式軟件測試中的應(yīng)用[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2007,7(5),9-11。
[8] 金維佳,施小敏.基于嵌入式軟件的覆蓋測試問題研究[J].信息技術(shù),2011(4):117-120.
[9] 楊俊,張倩,林依剛.一種嵌入式軟件覆蓋測試方法[J].指揮信息系統(tǒng)與技術(shù),2010,1(6),24-26,69.
[10] 劉穎,王英,劉漫丹.嵌入式軟件的覆蓋測試[J].自動化儀表,2012,33(6),63-66.
[11] 周雷.嵌入式代碼覆蓋率統(tǒng)計方法[J].計算機(jī)應(yīng)用與軟件。2014,31(5),326-327.
[12] 浦云明,丁躍潮.基于DD路徑的代碼覆蓋技術(shù)及應(yīng)用[J].2007,28(14),3306-3309.
[13] 浦云明,張杰敏,林穎賢。代碼覆蓋測試技術(shù)在MODE-S應(yīng)答機(jī)中的應(yīng)用[J].計算機(jī)應(yīng)用與軟件,2008,25(7):131-133,148.
[14] 于炳霞.基于嵌入式軟件的覆蓋測試技術(shù)研究[D].南京:南京航空航天大學(xué),2010.
[15] 余鋒林,劉小明,朱艷,等.BWDSP100集成開發(fā)環(huán)境設(shè)計與實現(xiàn)[J].中國集成電路,2012,21(6):25-29.
[16] 劉小明,朱艷.BWDSP100數(shù)字信號處理器的指令緩存器設(shè)計[J].中國集成電路,2013,22(4):48-50,56.
[17] 李普曼,拉喬伊,默.C++ Primer中文版[M].王剛,楊巨峰,譯.5.北京:電子工業(yè)出版社,2013.
[18] 林廣棟,劉谷,王強(qiáng),等.一種DWARF格式行號調(diào)試信息解析方法[J].現(xiàn)代計算機(jī),2014,482:3-9.