李國強(qiáng) 張 虹 王海瑞
(1.西安電子工程研究所 西安 710100;2.裝甲兵軍事代表局駐西安地區(qū)軍事代表室 西安 710000)
隨著計算機(jī)技術(shù)的廣泛應(yīng)用,在軍工武器裝備的研制中從系統(tǒng)級到部件級都采用了大量的計算機(jī)硬件和軟件,這些軟硬件組合在一起實(shí)現(xiàn)武器裝備的功能。在這樣的系統(tǒng)中無論硬件還是軟件都存在設(shè)計缺陷與錯誤,有可能引起裝備的故障,甚至可能造成嚴(yán)重?fù)p失。
隨著軟件的規(guī)模和復(fù)雜度的增加,在軟件開發(fā)的各個階段中,產(chǎn)生錯誤的時機(jī)很多,如軟件需求的敘述、軟件架構(gòu)的設(shè)計、軟件編碼都可能產(chǎn)生錯誤;就連程序輸入也可能引入錯誤,軟件錯誤造成的災(zāi)難也越來越嚴(yán)重。
國內(nèi)外已有大量事例說明,當(dāng)代武器裝備的大量災(zāi)難性事故是由軟件故障引起的,如何減少軟件缺陷成為軟件界面臨的嚴(yán)峻挑戰(zhàn)。軟件測試是發(fā)現(xiàn)軟件錯誤和缺陷的最好的方法,也是保證軟件質(zhì)量的關(guān)鍵手段,因此開展軟件測試技術(shù)的研究已引起了國內(nèi)外軟件業(yè)的高度重視。
軟件測試是為了發(fā)現(xiàn)代碼中的錯誤而分析或執(zhí)行代碼的過程,是保證軟件質(zhì)量及可靠性的手段,能夠?yàn)楫a(chǎn)品設(shè)計定型提供依據(jù)。對于軟件測試,可以從下面幾種不同的角度分類:
從是否需要執(zhí)行被測試軟件的角度分類,可以分為靜態(tài)測試和動態(tài)測試。如果在測試過程中執(zhí)行被測試軟件,則稱之為動態(tài)測試,相反,在測試過程中不執(zhí)行被測試軟件,則稱之為靜態(tài)測試。
從測試是否針對軟件結(jié)構(gòu)預(yù)算法的角度分類,分為白盒測試、黑盒測試。若在測試過程中,不關(guān)心軟件的內(nèi)部結(jié)構(gòu)和具體的實(shí)現(xiàn)算法,在無需了解軟件結(jié)構(gòu)預(yù)算法的情況下進(jìn)行測試,則稱之為黑盒測試,反之,如果需要對軟件的內(nèi)部結(jié)構(gòu)和算法進(jìn)行測試,則稱之為白盒測試。
根據(jù)軟件研制的過程,在不同的軟件研制階段所要關(guān)注的點(diǎn)不同,采用的測試技術(shù)也不同,因此軟件的軟件測試工作本身也要按照階段進(jìn)行,在每個階段有著不同的測試方法,整個測試過程可以分為單元測試、集成測試、系統(tǒng)測試和驗(yàn)收測試和回歸測試等五個階段(見表1)。
表1 軟件測試技術(shù)分類
靜態(tài)測試又稱靜態(tài)分析,靜態(tài)測試是不執(zhí)行軟件程序而尋找文檔、代碼中可能存在的缺陷或評估程序代碼的過程[1]。靜態(tài)測試可以人工進(jìn)行,也可以借助專門的軟件測試工具自動進(jìn)行。靜態(tài)測試主要包括由人工進(jìn)行文檔審查、代碼走查以及由軟件工具自動進(jìn)行的工具輔助靜態(tài)分析。
2.1.1 文檔審查
文檔審查遵循軟件同仁審查的方法和過程,即組成評審組,對照軟件需求規(guī)格說明、軟件設(shè)計說明檢查單檢查需求、設(shè)計易出現(xiàn)的錯誤。
審查軟件需求規(guī)格說明著重于檢查軟件需求是否符合系統(tǒng)需求,軟件需求的描述和解釋是否完整、準(zhǔn)確等。主要審查的內(nèi)容如下:
a.軟件需求與系統(tǒng)需求的符合性;
b.軟件需求的準(zhǔn)確性及一致性;
c.軟件需求與目標(biāo)機(jī)的兼容性;
d.軟件需求的可測試性;
e.軟件需求與所依標(biāo)準(zhǔn)的符合性;
f.軟件需求到系統(tǒng)需求的可追蹤性;
g.算法的準(zhǔn)確性。
審查軟件設(shè)計說明著重于分析設(shè)計是否與需求定義一致,所采用的數(shù)值方法和算法是否適用于待解問題,對軟件的劃分是否與待解問題相適應(yīng),需求是否都被滿足了等。主要審查的內(nèi)容如下:
a.軟件設(shè)計與軟件需求的符合性;
b.軟件設(shè)計的準(zhǔn)確性和一致性;
c.軟件設(shè)計與目標(biāo)機(jī)的兼容性;
d.軟件設(shè)計的可測試性;
e.軟件設(shè)計與編寫標(biāo)準(zhǔn)的符合性;
f.軟件設(shè)計到軟件需求的可追蹤性;
g.算法的準(zhǔn)確性;
h.控制流描述的正確性;
i.數(shù)據(jù)設(shè)計說明的完備性、一致性的和易理解性;
j.軟件具有健壯性;
k.軟件劃分的完整性;
l.可靠性、安全性設(shè)計的恰當(dāng)性。
2.1.2 代碼走查
代碼走查是早期可以開展的測試活動,是發(fā)現(xiàn)軟件錯誤的有效手段,在開發(fā)過程中可以通過開評審會的形式開展。參照代碼檢查單檢查編碼中易出現(xiàn)的錯誤,檢查代碼和設(shè)計的一致性,代碼對標(biāo)準(zhǔn)的遵循、可讀性,代碼的邏輯表達(dá)的正確性,代碼結(jié)構(gòu)的合理性等方面;可以發(fā)現(xiàn)違背程序編寫標(biāo)準(zhǔn)的問題,程序中不安全、不明確和模糊的部分,找出程序中不可移植部分、違背程序編程風(fēng)格的問題,包括變量檢查、命名和類型審查、程序邏輯審查、程序語法和程序結(jié)構(gòu)檢查等內(nèi)容。程序邏輯檢查一般有兩種審查方法,即深度優(yōu)先遍歷和廣度優(yōu)先遍歷方法。深度優(yōu)先遍歷通過追蹤每個子程序的主要邏輯行,將主要邏輯行全部追蹤完,然后再開始追蹤第二條路徑。廣度優(yōu)先遍歷從主要行開始,按排列順序依次檢查較低層的程序段。廣度優(yōu)先遍歷有助于很快了解程序全貌,深度優(yōu)先遍歷適于詳細(xì)查閱功能處理步驟[2]。
2.1.3 靜態(tài)分析
靜態(tài)分析是一種利用測試工具對代碼進(jìn)行的機(jī)械性和格式化的分析方法。靜態(tài)分析速度快,工作質(zhì)量穩(wěn)定,可在現(xiàn)性強(qiáng);靜態(tài)分析可以只分析某些特定的缺陷,或只分析某些特定的模塊,而不會受到其它缺陷和其他模塊的影響。靜態(tài)分析主要包括:包括控制流分析、數(shù)據(jù)流分析、接口分析、表達(dá)式分析。
控制流分析:控制流圖是一宗表示程序控制結(jié)構(gòu)的有向圖,可用于說明程序的邏輯路徑。如果一個輸入引起一條路徑的執(zhí)行,那么這條路徑就成為可達(dá),否則不可達(dá);控制流分析能檢測出程序是否存在不可達(dá)和死循環(huán)的情況。
數(shù)據(jù)流分析:數(shù)據(jù)流分析是通過檢查變量的定義和引用關(guān)系來發(fā)現(xiàn)程序中的錯誤;如果程序中某一條語句的執(zhí)行能改變某個變量的值,則稱這個變量在該語句中定義;如果某一條語句的執(zhí)行引用了某變量的值,則稱這條語句引用了該變量;通過定義和引用的關(guān)系,可以發(fā)現(xiàn)數(shù)據(jù)流的異常。
接口分析:接口分析主要用在程序靜態(tài)分析和設(shè)計分析。接口設(shè)計分析涉及模塊之間接口的一致性以及模塊與外部數(shù)據(jù)庫之間的一致性。接口分析涉及子程序以及函數(shù)之間的接口一致性,包括檢查形參與實(shí)參類型、個數(shù)、維數(shù)、順序的一致性。當(dāng)程序模塊之間的數(shù)據(jù)或控制傳遞使用公共變量塊或全局變量時,也應(yīng)檢查它們的一致性。
表達(dá)式分析:某些錯誤的出現(xiàn)與程序中表達(dá)式的計算相關(guān)。如果進(jìn)行對表達(dá)式的分析,就可以避免這些錯誤。表達(dá)式錯誤主要有以下幾種:括號使用不正確,數(shù)組應(yīng)用錯誤,作為除數(shù)的變量可能為零,作為開平方的變量可能為負(fù)數(shù),作為正切值的變量為∏/2,浮點(diǎn)數(shù)變量比較時產(chǎn)生的錯誤。
動態(tài)測試是建立在對程序的執(zhí)行過程中,根據(jù)是否對被測對象內(nèi)部的了解,分析輸出以發(fā)現(xiàn)錯誤的過程,如果抽樣測試數(shù)據(jù)滿足一定要求,通過測試可以發(fā)現(xiàn)程序中大多數(shù)錯誤,并且可以評估程序的質(zhì)量(正確性、可靠性等)。動態(tài)測試技術(shù)具有以下特點(diǎn):
a.實(shí)際運(yùn)行被測試程序,獲取程序運(yùn)行的真實(shí)情況、動態(tài)情況并進(jìn)行分析;
b.必須設(shè)計測試數(shù)據(jù)來運(yùn)行程序,測試質(zhì)量依賴于設(shè)計的測試數(shù)據(jù);
c.設(shè)計測試數(shù)據(jù)、分析測試結(jié)果工作量大,使開展測試工作費(fèi)時、費(fèi)力;
d.動態(tài)測試中涉及多方面工作,人員多、設(shè)備多、數(shù)據(jù)多,要求有較好的管理和工作規(guī)程。
動態(tài)測試包括三部分核心內(nèi)容:設(shè)計測試數(shù)據(jù)、執(zhí)行程序及驗(yàn)證程序的輸出結(jié)果。圍繞核心還有文件編制、數(shù)據(jù)管理、操作規(guī)程化及工具應(yīng)用等方面工作,其中最重要的問題是設(shè)計測試數(shù)據(jù)的策略,它是動態(tài)測試有效、高效的關(guān)鍵。動態(tài)測試主要有黑盒測試和白盒測試。黑盒測試和白盒測試實(shí)際上是測試數(shù)據(jù)選擇的兩種方式[3]。
任何工程產(chǎn)品都可以使用以下的兩種方法之一進(jìn)行測試:已知產(chǎn)品的功能設(shè)計規(guī)格,通過測試證明實(shí)現(xiàn)的每個功能是否符合要求;已知產(chǎn)品的內(nèi)部工作過程,通過測試證明每種內(nèi)部操作是否符合設(shè)計規(guī)格要求,所有內(nèi)部成分是否已經(jīng)經(jīng)過驗(yàn)證。這兩種立場不同的測試,就是常用的兩種測試方法:黑盒測試與白盒測試。
2.2.1 黑盒測試(Black-box Testing)
黑盒測試又稱功能測試,是一種按照軟件需求規(guī)格說明設(shè)計測試數(shù)據(jù)的方法。它把程序看作內(nèi)部不可見的黑盒子,完全不需考慮程序內(nèi)部結(jié)構(gòu)和內(nèi)部特征,測試者只需了解程序輸入和輸出之間的關(guān)系,或是程序的功能,完全依靠需求規(guī)格說明確定測試數(shù)據(jù),判定測試結(jié)果的正確性。黑盒測試方法有等價類劃分、邊界值分析、隨機(jī)測試等測試用例設(shè)計方法。
2.2.1.1 等價類劃分
因?yàn)橐褂酶F舉輸入進(jìn)行測試是不可能的。因此,人們在設(shè)計測試用例時,試圖局限于使用輸入的一個小子集進(jìn)行測試。在選擇這個小子集時,又希望它是發(fā)現(xiàn)錯誤概率最大的子集。一個基本的原則就是這個有限子集應(yīng)能代表所有可能的輸入全集。按照這個思路,我們把輸入全集劃分為若干等價類,這樣就有可能得到一種假設(shè),即測試某等價類的代表值就等價于對這一類其它值的測試。也就是說,如果某個等價類中的一個測試用例查出了錯誤,這一等價類中的其它測試用例也會查出同樣的錯誤。反之,若某個等價類中的測試用例未查出錯誤,那么,這一等價類中的其它測試用例也同樣查不出錯誤。等價類劃分就是這種劃分輸入全集的技術(shù),它可導(dǎo)致發(fā)現(xiàn)不同錯誤種類的測試用例設(shè)計,以減少所需的測試用例總數(shù)。
采用等價類劃分技術(shù)設(shè)計測試用例分兩個步驟:劃分等價類和確定測試用例。
劃分等價類的方法是根據(jù)每個輸入條件(通常是需求規(guī)格說明中的一句話或一個短語)找出等價類。劃分等價類時,必須仔細(xì)分析和推敲需求規(guī)格說明中的每一項(xiàng)需求,特別是功能需求,不但要考慮每個輸入條件,也要考慮每個輸出條件。
等價類劃分可分為兩種不同的情況:有效等價類和無效等價類。有效等價類指的是對于程序的需求規(guī)格說明是合理的、有意義的輸入數(shù)據(jù)構(gòu)成的集合。利用有效等價類可檢驗(yàn)程序是否實(shí)現(xiàn)了需求規(guī)格說明中規(guī)定的功能和性能。無等價類指的是對軟件需求規(guī)格說明而言是不合理或無意義的輸入數(shù)據(jù)所構(gòu)成的集合。表2是一個等價類劃分的列子,H、M、S作為當(dāng)前系統(tǒng)時間。
表2 等價類劃分的例子
2.2.1.2 邊界值分析
邊界值分析法就是對輸入或輸出的邊界值進(jìn)行測試的方法。這里所說的邊界值包含邊界值的兩邊的值。邊界值測試的原理是:錯誤更有可能出現(xiàn)在輸入變量的極值附近,基本思想是:在最小值、略高于最小值、正常值、略低于最大值、最大值處取輸入變量的值。
在測試邊界條件時要遵循以下幾個準(zhǔn)則:
a.若輸入條件規(guī)定了取值的范圍,則應(yīng)取剛達(dá)到這個范圍的邊界值,以及剛超過這個范圍邊界的值作為測試數(shù)據(jù);
b.若輸入條件規(guī)定了取值的個數(shù),則應(yīng)使用最大個數(shù)、最小個數(shù)、比最小個數(shù)少一個、比最大個數(shù)多一個的數(shù)作為測試數(shù)據(jù);
c.若程序的軟件需求規(guī)格說明指明輸入或輸出域是個有序集合,應(yīng)注意選擇有序集的第一個和最后一個元素作為測試用例。
d.分析軟件需求規(guī)格說明,找出其他可能的邊界條件。
2.2.1.3 隨機(jī)測試
隨機(jī)測試指測試數(shù)據(jù)是在所有可能輸入值中隨機(jī)選取的測試數(shù)據(jù)的方法,是一種基本的黑盒測試方法。隨機(jī)選取用隨機(jī)模擬的方法,包括用偽隨機(jī)數(shù)發(fā)生器、硬件隨機(jī)模擬器產(chǎn)生測試數(shù)據(jù)。測試人員只需規(guī)定輸入變量的取值區(qū)間,在需要時提供必要的變換機(jī)制,使產(chǎn)生的隨機(jī)數(shù)服從預(yù)期的概率分布。對包括實(shí)時軟件在內(nèi)的許多程序,隨機(jī)測試有較高的效費(fèi)比。但是,由于測試用例應(yīng)該包括預(yù)期輸出結(jié)果,對隨機(jī)測試來說這是比較困難的。這個問題有兩個解決方法。一個是對每一組測試數(shù)據(jù)都用人工方法得出其預(yù)期結(jié)果,其過程繁瑣影響了隨機(jī)測試的效率。另一個方法是提供一個性質(zhì)相同的,取一經(jīng)過驗(yàn)證的程序作為參照,對測試結(jié)果進(jìn)行比較。但是在多數(shù)情況下,找到這樣一個可供比較的程序比較難。因此,在選用隨機(jī)測試方法時,要考慮預(yù)期的測試結(jié)果是否容易得到。
隨機(jī)測試的缺陷是不能事先將輸入存入文檔,在排錯時無法重現(xiàn)測試中錯誤發(fā)生的過程,也無法進(jìn)行回歸測試。補(bǔ)救的方法是將隨機(jī)產(chǎn)生的測試數(shù)據(jù)記錄備用。
2.2.2 白盒測試(White-box Testing)
白盒測試作為結(jié)構(gòu)測試方法,是一種按照程序內(nèi)部邏輯結(jié)構(gòu)和編碼結(jié)構(gòu)設(shè)計測試數(shù)據(jù)的測試方法。它會根據(jù)代碼的組織結(jié)構(gòu)查找軟件缺陷,要求測試人員對軟件的結(jié)構(gòu)和作用有詳細(xì)的了解。測試人員利用程序內(nèi)部的邏輯結(jié)構(gòu)及相關(guān)信息設(shè)計或選擇測試用例。
2.2.2.1 語句覆蓋
語句覆蓋是指在執(zhí)行測試用例時,使程序的每條語句都至少執(zhí)行一次,但要求設(shè)計足夠多的測試用例,并且語句覆蓋并不能發(fā)現(xiàn)某些邏輯錯誤[4]。
如圖1所示流程圖,要使其達(dá)到語句覆蓋,只需選取:A=2,B=0,X=3。
但是這個測試還不徹底,如果AND誤寫成了OR,上面的語句覆蓋測試就發(fā)現(xiàn)不了。
圖1 一個程序的流程圖
2.2.2.2 判定覆蓋
判定覆蓋又稱分支覆蓋,判定覆蓋是執(zhí)行足夠的測試用例,使得程序中每個判定都獲得一次“真”或“假”值,或者使每一個分支都至少通過1次覆蓋測試策略。
對圖1來說,設(shè)計兩組測試數(shù)據(jù)就可使它通過路徑ace和abd或路徑acd和abe達(dá)到判定覆蓋(見表3)。
表3 判定覆蓋測試用例
判定覆蓋也有不完全測試的情況,如上面兩個測試用例未能測試沿著路徑abd執(zhí)行時,值是否保持不變。
2.2.2.3 條件覆蓋
條件覆蓋式執(zhí)行足夠的測試用例,使得判定中的每個條件獲得各種可能的值的測試策略。
條件覆蓋要求設(shè)計足夠多的測試用例,使得判定中的每個條件獲得各種可能的結(jié)果。同時每個入口點(diǎn)和出口點(diǎn)至少要喚醒一次。
圖1的流程圖中,在a點(diǎn)有條件:A>1和B=0,在b點(diǎn)有條件:A=2和X>1,要達(dá)到條件覆蓋,需要足夠多的測試用例,使得在a點(diǎn)有A>1,A≤1,B=0,B≠0,在 b 點(diǎn)有 A=2,A≠2,X >1,X≤1。我們選如表4所示的兩組測試輸入。
表4 條件覆蓋測試用例
由上例可以看出,條件覆蓋并不能保證判定覆蓋。
2.2.2.4 判定/條件覆蓋
判定條件覆蓋是執(zhí)行足夠的測試用例,使得判定中的每個條件獲得各種可能的值,并使得每個判定取得各種可能的結(jié)果的測試策略。
圖1的流程圖,可用表5所示兩組測試輸入達(dá)到判定/條件覆蓋。
表5 判定/條件覆蓋測試用例
判定/條件覆蓋準(zhǔn)則滿足判定覆蓋準(zhǔn)則和條件覆蓋準(zhǔn)則。判定/條件覆蓋準(zhǔn)則的缺點(diǎn)是未考慮條件的組合情況。
2.2.2.5 條件組合覆蓋
條件組合覆蓋是執(zhí)行足夠的測試用例,使得每個判定中的條件的各種組合至少出現(xiàn)1次的測試策略。其特點(diǎn)是覆蓋較充分,滿足條件組合的覆蓋測試用例也一定滿足判定覆蓋、條件覆蓋、判定/條件覆蓋。
對圖1的流程圖,可選用表6的測試輸入組合。
表6 多重條件覆蓋測試用例
2.2.2.6 更改的判定/條件覆蓋(MC/DC)
更改的判定/條件覆蓋要求設(shè)計足夠多的測試用例,使得判定中每個條件的所有可能結(jié)果至少出現(xiàn)一次,每個判定本身的所有可能結(jié)果也至少出現(xiàn)一次,每個入口點(diǎn)和出口點(diǎn)至少要喚醒一次。并且每個條件都顯示能單獨(dú)影響判定結(jié)果[5]。
判斷每個條件是否能單獨(dú)影響判定結(jié)果的方法是:在固定其它條件值的同時變化要檢查的條件。更改的判定/條件覆蓋繼承了多重條件覆蓋的優(yōu)點(diǎn),同時只是線性地增加了測試用例的數(shù)量。例:A and B,其全部的條件組合見表7。
表7 A and B全部條件組合測試用例
測試用例1和3說明條件A獨(dú)立地影響測試結(jié)果,測試用例1和2說明條件B獨(dú)立地影響測試結(jié)果,所以測試用例1,2,3是必須的。
軟件測試是一個系統(tǒng)性的工作,涉及軟件研制的各個階段,本文所論述的關(guān)鍵技術(shù)覆蓋整個軟件測試的全過程,但是在實(shí)際工作中可以根據(jù)被測軟件的情況,選擇采用合適的技術(shù)與方法,也可以利用成熟的測試工具進(jìn)行。在多年的軟件測試工作中,筆者利用上述關(guān)鍵技術(shù)完成了幾十個型號產(chǎn)品上百個軟件配置項(xiàng)的測試工作,發(fā)現(xiàn)了大量的軟件設(shè)計缺陷與錯誤,有效地保證了型號產(chǎn)品的質(zhì)量與可靠性。
[1] 徐芳主編.軟件測試技術(shù)[M].北京:機(jī)械工業(yè)出版社,2006.
[2] 王健編著.軟件測試員培訓(xùn)教材[M].北京:電子工業(yè)出版社,2003.
[3]賀紅衛(wèi),楊芳等譯.實(shí)用軟件測試過程[M].北京:機(jī)械工業(yè)出版社,2004.
[4] 尹黨輝,于佳偉,李虎.軟件覆蓋測試技術(shù)研究[J].中國測試,2012,38(z):42-44.
[5]胡江衛(wèi),吳偉等.嵌入式軟件測試[M].北京:機(jī)械工業(yè)出版社,2009.