軟件單元測(cè)試的設(shè)計(jì)方法
寫在前面:
軟件單元測(cè)試的設(shè)計(jì)是一個(gè)系統(tǒng)化的過(guò)程,旨在驗(yàn)證代碼的最小可測(cè)試部分(通常是函數(shù)或方法)是否按預(yù)期工作。軟件單元測(cè)試的設(shè)計(jì)是確保代碼正確性和可靠性的關(guān)鍵步驟。在軟件單元測(cè)試中,等價(jià)類測(cè)試是一種很重要的測(cè)試設(shè)計(jì)方法,它通過(guò)將輸入數(shù)據(jù)劃分為若干個(gè)等價(jià)類,并從每個(gè)等價(jià)類中選取代表性的數(shù)據(jù)進(jìn)行測(cè)試,以提高測(cè)試的全面性和效率。
01.
等價(jià)類劃分法
在設(shè)計(jì)測(cè)試用例的時(shí)候,我們通常采用等價(jià)類劃分法。等價(jià)類劃分法的原理就是將無(wú)窮多數(shù)據(jù)縮減到有限個(gè)等價(jià)區(qū)域中,通過(guò)測(cè)試等價(jià)區(qū)域完成窮盡測(cè)試。
等價(jià)類劃分要滿足3個(gè)原則:
1. 互斥性:各個(gè)等價(jià)類之間應(yīng)該是互斥的,即沒(méi)有交集,確保每個(gè)輸入數(shù)據(jù)只屬于一個(gè)等價(jià)類。
2. 全面性:所有等價(jià)類的并集仍然是原始的輸入域,即所有劃分的等價(jià)類應(yīng)該覆蓋所有可能的輸入條件,確保沒(méi)有遺漏。
3. 以一代全:任意一個(gè)等價(jià)類中,所有數(shù)據(jù)相互“等價(jià)”,指一組輸入數(shù)據(jù),這些數(shù)據(jù)在程序的某個(gè)特定功能上被認(rèn)為是等價(jià)的,即它們對(duì)程序的執(zhí)行結(jié)果產(chǎn)生的影響是相同的。
等價(jià)類分為有效等價(jià)類和無(wú)效等價(jià)類
有效等價(jià)類:指那些在正常操作條件下預(yù)期程序能夠正確處理的輸入數(shù)據(jù)集合,對(duì)應(yīng)有效輸入域的數(shù)據(jù),用以檢測(cè)被測(cè)系統(tǒng)能否正確完成指定功能。
無(wú)效等價(jià)類:指那些預(yù)期程序無(wú)法正確處理或應(yīng)該拒絕的輸入數(shù)據(jù)集合,對(duì)應(yīng)無(wú)效輸入域中的數(shù)據(jù),用以考察被測(cè)系統(tǒng)的容錯(cuò)性。
02.
如何劃分等價(jià)類
那么如何劃分等價(jià)類呢?
1. 識(shí)別輸入條件:確定軟件的輸入條件,包括用戶輸入、系統(tǒng)參數(shù)、外部接口等。
2. 確定輸入域:對(duì)于數(shù)值型輸入,確定其取值范圍;對(duì)于枚舉型輸入,列出所有可能的枚舉值。
3. 劃分有效等價(jià)類:識(shí)別那些符合軟件規(guī)格說(shuō)明的輸入條件,這些構(gòu)成了有效等價(jià)類。根據(jù)業(yè)務(wù)邏輯和規(guī)則,將輸入條件分組,每組構(gòu)成一個(gè)有效等價(jià)類。
4. 劃分無(wú)效等價(jià)類:識(shí)別那些不符合軟件規(guī)格說(shuō)明的輸入條件,這些構(gòu)成了無(wú)效等價(jià)類。考慮軟件如何處理錯(cuò)誤輸入,例如空值、非法字符、超出范圍的數(shù)值等。
5. 考慮邊界值:對(duì)于每個(gè)等價(jià)類,特別是處于邊界的等價(jià)類,識(shí)別邊界值。這些值往往是錯(cuò)誤發(fā)生的高發(fā)區(qū)。
如輸入條件規(guī)定了取值范圍時(shí),應(yīng)劃分一個(gè)有效等價(jià)類和兩個(gè)無(wú)效等價(jià)類(一個(gè)低于范圍,一個(gè)高于范圍)。如果輸入條件是一個(gè)布爾量,可以劃分一個(gè)有效等價(jià)類(真)和一個(gè)無(wú)效等價(jià)類(假)。當(dāng)輸入數(shù)據(jù)有多個(gè)可能的值時(shí),為每個(gè)值劃分一個(gè)有效等價(jià)類,并考慮一個(gè)無(wú)效等價(jià)類來(lái)覆蓋不符合任何有效值的輸入。
例如Year變量需滿足條件:1920<=year<=2012,范圍內(nèi)數(shù)值為有效等價(jià)類,<1920為一個(gè)無(wú)效等價(jià)類,>2012為一個(gè)無(wú)效等價(jià)類。

為有效等價(jià)類設(shè)計(jì)測(cè)試用例:

為無(wú)效等價(jià)類設(shè)計(jì)測(cè)試用例:

03.
邊界值分析
在許多情況下,邊界值往往是錯(cuò)誤容易發(fā)生的地方,因此應(yīng)特別注意邊界條件的處理。對(duì)于每個(gè)等價(jià)類,特別是有效等價(jià)類,考慮其邊界值,并可能將其視為單獨(dú)的測(cè)試用例。
在進(jìn)行邊界值分析的時(shí)候,首先要確定邊界值。根據(jù)需求規(guī)格,識(shí)別所有可能的邊界條件,如最大值、最小值、上界、下界等,確定每個(gè)輸入或輸出參數(shù)的邊界值。對(duì)于數(shù)值型數(shù)據(jù),通常需要考慮其最大值、最小值和緊鄰這些值的幾個(gè)點(diǎn)。對(duì)于非數(shù)值型數(shù)據(jù)(如字符串長(zhǎng)度、顏色選擇等),也要確定其邊界條件。
在設(shè)計(jì)測(cè)試用例的時(shí)候,要針對(duì)每個(gè)邊界值,設(shè)計(jì)相應(yīng)的測(cè)試用例。測(cè)試用例應(yīng)包括正常范圍內(nèi)的值、剛好在邊界上的值以及稍微超出邊界的值。特別注意那些“剛好”達(dá)到邊界條件的情況,因?yàn)檫@些問(wèn)題在實(shí)際應(yīng)用中往往更容易出現(xiàn)。
按照設(shè)計(jì)的測(cè)試用例執(zhí)行測(cè)試,觀察系統(tǒng)在邊界條件下的行為是否符合預(yù)期,是否存在錯(cuò)誤、異常或性能下降等問(wèn)題。
通過(guò)遵循這些步驟,可以在軟件單元測(cè)試中有效地應(yīng)用等價(jià)類測(cè)試方法,以確保軟件的功能安全性能得到充分驗(yàn)證。
04.
軟件單元測(cè)試環(huán)境
在軟件單元測(cè)試中,常見的測(cè)試環(huán)境有SIL、MIL、PIL和HIL,它們分別對(duì)應(yīng)不同的測(cè)試階段和目的:
1. MIL(Model in the Loop)模型在環(huán)測(cè)試
MIL測(cè)試是在模型開發(fā)階段進(jìn)行的,通過(guò)純軟件仿真的形式驗(yàn)證控制模型是否滿足功能需求。它通常發(fā)生在系統(tǒng)工程師為了驗(yàn)證算法,使用控制算法模型控制被控對(duì)象模型的場(chǎng)景下,或者軟件工程師做模型級(jí)別的集成測(cè)試。
2. SIL(Software in the Loop)軟件在環(huán)測(cè)試
SIL測(cè)試是在MIL之后進(jìn)行的,目的是驗(yàn)證自動(dòng)生成的代碼與算法模型的一致性。它使用與MIL相同的測(cè)試用例,檢查自動(dòng)生成的代碼的輸出是否與MIL階段的模型輸出一致。SIL測(cè)試通過(guò)運(yùn)行系統(tǒng)環(huán)境中的車輛模型和虛擬ECU中的I/O模型來(lái)模擬控制器所需的各種傳感器信號(hào),并能接收臺(tái)架傳感器的信號(hào)和虛擬ECU發(fā)出的控制信號(hào)。
3. PIL(Processor in the Loop)處理器在環(huán)測(cè)試
PIL測(cè)試是將自動(dòng)生成的代碼編譯為目標(biāo)處理器需要的形式,并下載到目標(biāo)處理器上運(yùn)行,以防止編譯過(guò)程引入新的錯(cuò)誤。PIL測(cè)試也是等效性測(cè)試,其方式與SIL類似,不同之處是編譯好的算法運(yùn)行在目標(biāo)處理器上,而SIL測(cè)試是在算法開發(fā)環(huán)境進(jìn)行的。
4. HIL(Hardware in the Loop)硬件在環(huán)測(cè)試
HIL測(cè)試通常在開發(fā)出完整的控制器后進(jìn)行,有時(shí)被控對(duì)象(如整車)還未完成開發(fā),或者使用真實(shí)被控對(duì)象進(jìn)行測(cè)試太危險(xiǎn)或成本高。在HIL測(cè)試中,采用真實(shí)控制控制器和虛擬被控對(duì)象,以進(jìn)行全面的功能驗(yàn)證和性能評(píng)估。HIL測(cè)試尤其適用于那些對(duì)實(shí)時(shí)響應(yīng)、外部設(shè)備交互要求嚴(yán)苛的嵌入式系統(tǒng),它能真實(shí)反映出軟件在實(shí)際運(yùn)行條件下的表現(xiàn),有效暴露系統(tǒng)在軟硬件集成層面可能出現(xiàn)的問(wèn)題。
這四種測(cè)試方法各自的特點(diǎn)如下:
◆ MIL關(guān)注模型層面的功能實(shí)現(xiàn)及測(cè)試覆蓋度情況。
◆ SIL關(guān)注的是生成的代碼與模型間的一致性。
◆ PIL關(guān)注的是代碼在目標(biāo)處理器上的運(yùn)行情況。
◆ HIL關(guān)注的是軟硬件集成后的整體系統(tǒng)表現(xiàn)。
05.
軟件單元測(cè)試覆蓋率
ISO26262 part6的表9—軟件單元級(jí)別的結(jié)構(gòu)覆蓋度指標(biāo)如下表所示:

1. 語(yǔ)句覆蓋:它關(guān)注的是程序中每個(gè)可執(zhí)行語(yǔ)句是否至少被執(zhí)行過(guò)一次。這是代碼覆蓋率分析中最基本的形式,其目的是確保測(cè)試用例能夠覆蓋到程序中的所有代碼行。
由于其簡(jiǎn)單性,語(yǔ)句覆蓋通常容易實(shí)現(xiàn)和維護(hù)。語(yǔ)句覆蓋并不保證程序的邏輯路徑被完全測(cè)試。例如,它不能保證所有的條件分支都被測(cè)試,或者所有的循環(huán)邊界都被觸及。為了達(dá)到100%的語(yǔ)句覆蓋,測(cè)試用例需要設(shè)計(jì)得能夠觸發(fā)程序中的每一個(gè)語(yǔ)句。語(yǔ)句覆蓋并不保證程序的質(zhì)量,因?yàn)榧词顾姓Z(yǔ)句都被執(zhí)行,也可能存在邏輯錯(cuò)誤未被發(fā)現(xiàn)。
例:


2. 分支覆蓋:它要求測(cè)試用例能夠覆蓋程序中所有可能的分支路徑。分支覆蓋關(guān)注的是程序中的控制流,特別是條件語(yǔ)句(如 if, else, switch 等)的真假分支是否都被執(zhí)行過(guò)至少一次。
分支覆蓋是路徑覆蓋的一個(gè)子集,它確保了程序中的每個(gè)分支都被測(cè)試。通過(guò)確保每個(gè)分支都被測(cè)試,分支覆蓋有助于發(fā)現(xiàn)那些只在特定條件下才會(huì)觸發(fā)的缺陷。為了達(dá)到分支覆蓋,測(cè)試用例需要設(shè)計(jì)得能夠觸發(fā)每個(gè)分支的真假條件。分支覆蓋比語(yǔ)句覆蓋更嚴(yán)格,因?yàn)樗鬁y(cè)試每個(gè)條件的真假分支。分支覆蓋并不保證所有可能的執(zhí)行路徑都被測(cè)試,特別是當(dāng)存在多個(gè)條件時(shí)。
3. MC/DC覆蓋:要求測(cè)試用例能夠覆蓋程序中所有可能的條件組合,并且每個(gè)條件都能獨(dú)立影響決策的結(jié)果。這是一種高級(jí)的白盒測(cè)試技術(shù),主要用于驗(yàn)證軟件中的邏輯條件和決策路徑。
MC/DC要求每個(gè)條件在決策中都能獨(dú)立地影響決策的結(jié)果。這意味著,當(dāng)改變一個(gè)條件的值時(shí),決策的結(jié)果也會(huì)隨之改變,而其他條件保持不變。MC/DC覆蓋了所有條件的所有可能結(jié)果,以及每個(gè)決策的所有可能結(jié)果。實(shí)現(xiàn)MC/DC可能需要更多的測(cè)試用例,因?yàn)槊總€(gè)條件都需要獨(dú)立地影響決策的結(jié)果。
MC/DC與其他覆蓋標(biāo)準(zhǔn)的區(qū)別:
與語(yǔ)句覆蓋的區(qū)別:語(yǔ)句覆蓋關(guān)注于代碼的行,而MC/DC關(guān)注于條件和決策的獨(dú)立影響。
與分支覆蓋的區(qū)別:
分支覆蓋要求測(cè)試每個(gè)分支的真假路徑,而MC/DC進(jìn)一步要求每個(gè)條件都能獨(dú)立地影響決策的結(jié)果。
讓我們通過(guò)一個(gè)具體的C語(yǔ)言函數(shù)例子來(lái)展示如何為語(yǔ)句覆蓋、分支覆蓋和MC/DC覆蓋設(shè)計(jì)測(cè)試用例。假設(shè)我們有以下函數(shù):

語(yǔ)句覆蓋測(cè)試用例:
語(yǔ)句覆蓋要求覆蓋函數(shù)中的每個(gè)語(yǔ)句至少一次。我們需要以下測(cè)試用例:
1. get_value(1,1)——覆蓋語(yǔ)句1(x和y都大于0)。
2. get_value(1,-1)——覆蓋語(yǔ)句2(x大于0,y小于等于0)。
3. get_value(-1,1)——覆蓋語(yǔ)句3(x小于等于0,y大于0)。
分支覆蓋測(cè)試用例:
分支覆蓋要求覆蓋每個(gè)條件的每個(gè)可能分支。我們需要以下測(cè)試用例:
1. get_value(1,1)——條件1真,條件2真。
2. get_value(1,-1)——條件1真,條件2假。
3. get_value(-1,1)——條件1假,條件2不可達(dá)(因?yàn)槲覀円呀?jīng)知道x小于等于0,所以不會(huì)檢查y)。
4. get_value(-1,-1)——條件1假,條件2假。
MC/DC覆蓋測(cè)試用例:
MC/DC覆蓋要求每個(gè)條件在決策中都能獨(dú)立地影響決策的結(jié)果。我們需要以下測(cè)試用例:
1. get_value(1,1)——條件1真,條件2真,覆蓋語(yǔ)句1。
2. get_value(1,-1)——條件1真,條件2假,覆蓋語(yǔ)句2。
3. get_value(-1,1)——條件1假,條件2不可達(dá),覆蓋語(yǔ)句3。
4. get_value(-1,-1)——條件1假,條件2假,再次覆蓋語(yǔ)句3,但這次是為了證明條件1的獨(dú)立影響。
為了滿足MC/DC的要求,我們需要確保改變?nèi)魏我粋€(gè)條件的值都能獨(dú)立地影響函數(shù)的返回值。這意味著我們需要額外的測(cè)試用例來(lái)證明條件1和條件2可以獨(dú)立地影響決策:
5. get_value(2, 0)——條件1真,條件2真,但y的值改變不影響決策,因?yàn)閤大于0。
6. get_value(0, 1)——條件1假,條件2真,但x的值改變不影響決策,因?yàn)閤不大于0。
通過(guò)這些測(cè)試用例,我們可以看到MC/DC覆蓋比語(yǔ)句覆蓋和分支覆蓋更為嚴(yán)格,它要求每個(gè)條件都能獨(dú)立地影響決策的結(jié)果。這有助于發(fā)現(xiàn)那些可能在條件組合中被隱藏的錯(cuò)誤。
許多現(xiàn)代的集成開發(fā)環(huán)境(IDE)和測(cè)試工具都支持語(yǔ)句覆蓋和分支覆蓋,可以自動(dòng)收集和報(bào)告覆蓋率數(shù)據(jù)。一些自動(dòng)化測(cè)試工具可以輔助實(shí)現(xiàn)MC/DC,通過(guò)分析代碼邏輯并生成相應(yīng)的測(cè)試用例。

作者
邊俊
磐時(shí)創(chuàng)始人/首席安全專家
汽車安全社區(qū)SASETECH發(fā)起人;智能網(wǎng)聯(lián)預(yù)期功能安全工作組核心成員;國(guó)內(nèi)最早從事汽車功能安全、預(yù)期功能安全的專家之一
-
測(cè)試
+關(guān)注
關(guān)注
9文章
6293瀏覽量
131515 -
軟件
+關(guān)注
關(guān)注
69文章
5341瀏覽量
91719 -
汽車安全
+關(guān)注
關(guān)注
4文章
347瀏覽量
35472
發(fā)布評(píng)論請(qǐng)先 登錄
MCU進(jìn)行單元測(cè)試的方法
單元測(cè)試/集成測(cè)試自動(dòng)化工具--WinAMS
如何提高嵌入式軟件單元測(cè)試效率
系統(tǒng)測(cè)試、單元測(cè)試、集成測(cè)試、驗(yàn)收測(cè)試、回歸測(cè)試
單元測(cè)試常用的方法
什么是單元測(cè)試_單元測(cè)試的目的是什么
java單元測(cè)試的好處
什么是單元測(cè)試,為什么要做單元測(cè)試
MCU如何進(jìn)行單元測(cè)試
RT-Thread上的單元測(cè)試:什么是單元測(cè)試?單元測(cè)試的作用是什么?
嵌入軟件單元測(cè)試工具的作用
邊聊安全 | 軟件單元測(cè)試的設(shè)計(jì)方法
評(píng)論