軟件單元測試的設(shè)計方法
寫在前面:
軟件單元測試的設(shè)計是一個系統(tǒng)化的過程,旨在驗證代碼的最小可測試部分(通常是函數(shù)或方法)是否按預期工作。軟件單元測試的設(shè)計是確保代碼正確性和可靠性的關(guān)鍵步驟。在軟件單元測試中,等價類測試是一種很重要的測試設(shè)計方法,它通過將輸入數(shù)據(jù)劃分為若干個等價類,并從每個等價類中選取代表性的數(shù)據(jù)進行測試,以提高測試的全面性和效率。
01.
等價類劃分法
在設(shè)計測試用例的時候,我們通常采用等價類劃分法。等價類劃分法的原理就是將無窮多數(shù)據(jù)縮減到有限個等價區(qū)域中,通過測試等價區(qū)域完成窮盡測試。
等價類劃分要滿足3個原則:
1. 互斥性:各個等價類之間應該是互斥的,即沒有交集,確保每個輸入數(shù)據(jù)只屬于一個等價類。
2. 全面性:所有等價類的并集仍然是原始的輸入域,即所有劃分的等價類應該覆蓋所有可能的輸入條件,確保沒有遺漏。
3. 以一代全:任意一個等價類中,所有數(shù)據(jù)相互“等價”,指一組輸入數(shù)據(jù),這些數(shù)據(jù)在程序的某個特定功能上被認為是等價的,即它們對程序的執(zhí)行結(jié)果產(chǎn)生的影響是相同的。
等價類分為有效等價類和無效等價類
有效等價類:指那些在正常操作條件下預期程序能夠正確處理的輸入數(shù)據(jù)集合,對應有效輸入域的數(shù)據(jù),用以檢測被測系統(tǒng)能否正確完成指定功能。
無效等價類:指那些預期程序無法正確處理或應該拒絕的輸入數(shù)據(jù)集合,對應無效輸入域中的數(shù)據(jù),用以考察被測系統(tǒng)的容錯性。
02.
如何劃分等價類
那么如何劃分等價類呢?
1. 識別輸入條件:確定軟件的輸入條件,包括用戶輸入、系統(tǒng)參數(shù)、外部接口等。
2. 確定輸入域:對于數(shù)值型輸入,確定其取值范圍;對于枚舉型輸入,列出所有可能的枚舉值。
3. 劃分有效等價類:識別那些符合軟件規(guī)格說明的輸入條件,這些構(gòu)成了有效等價類。根據(jù)業(yè)務(wù)邏輯和規(guī)則,將輸入條件分組,每組構(gòu)成一個有效等價類。
4. 劃分無效等價類:識別那些不符合軟件規(guī)格說明的輸入條件,這些構(gòu)成了無效等價類??紤]軟件如何處理錯誤輸入,例如空值、非法字符、超出范圍的數(shù)值等。
5. 考慮邊界值:對于每個等價類,特別是處于邊界的等價類,識別邊界值。這些值往往是錯誤發(fā)生的高發(fā)區(qū)。
如輸入條件規(guī)定了取值范圍時,應劃分一個有效等價類和兩個無效等價類(一個低于范圍,一個高于范圍)。如果輸入條件是一個布爾量,可以劃分一個有效等價類(真)和一個無效等價類(假)。當輸入數(shù)據(jù)有多個可能的值時,為每個值劃分一個有效等價類,并考慮一個無效等價類來覆蓋不符合任何有效值的輸入。
例如Year變量需滿足條件:1920<=year<=2012,范圍內(nèi)數(shù)值為有效等價類,<1920為一個無效等價類,>2012為一個無效等價類。
為有效等價類設(shè)計測試用例:
為無效等價類設(shè)計測試用例:
03.
邊界值分析
在許多情況下,邊界值往往是錯誤容易發(fā)生的地方,因此應特別注意邊界條件的處理。對于每個等價類,特別是有效等價類,考慮其邊界值,并可能將其視為單獨的測試用例。
在進行邊界值分析的時候,首先要確定邊界值。根據(jù)需求規(guī)格,識別所有可能的邊界條件,如最大值、最小值、上界、下界等,確定每個輸入或輸出參數(shù)的邊界值。對于數(shù)值型數(shù)據(jù),通常需要考慮其最大值、最小值和緊鄰這些值的幾個點。對于非數(shù)值型數(shù)據(jù)(如字符串長度、顏色選擇等),也要確定其邊界條件。
在設(shè)計測試用例的時候,要針對每個邊界值,設(shè)計相應的測試用例。測試用例應包括正常范圍內(nèi)的值、剛好在邊界上的值以及稍微超出邊界的值。特別注意那些“剛好”達到邊界條件的情況,因為這些問題在實際應用中往往更容易出現(xiàn)。
按照設(shè)計的測試用例執(zhí)行測試,觀察系統(tǒng)在邊界條件下的行為是否符合預期,是否存在錯誤、異常或性能下降等問題。
通過遵循這些步驟,可以在軟件單元測試中有效地應用等價類測試方法,以確保軟件的功能安全性能得到充分驗證。
04.
軟件單元測試環(huán)境
在軟件單元測試中,常見的測試環(huán)境有SIL、MIL、PIL和HIL,它們分別對應不同的測試階段和目的:
1. MIL(Model in the Loop)模型在環(huán)測試
MIL測試是在模型開發(fā)階段進行的,通過純軟件仿真的形式驗證控制模型是否滿足功能需求。它通常發(fā)生在系統(tǒng)工程師為了驗證算法,使用控制算法模型控制被控對象模型的場景下,或者軟件工程師做模型級別的集成測試。
2. SIL(Software in the Loop)軟件在環(huán)測試
SIL測試是在MIL之后進行的,目的是驗證自動生成的代碼與算法模型的一致性。它使用與MIL相同的測試用例,檢查自動生成的代碼的輸出是否與MIL階段的模型輸出一致。SIL測試通過運行系統(tǒng)環(huán)境中的車輛模型和虛擬ECU中的I/O模型來模擬控制器所需的各種傳感器信號,并能接收臺架傳感器的信號和虛擬ECU發(fā)出的控制信號。
3. PIL(Processor in the Loop)處理器在環(huán)測試
PIL測試是將自動生成的代碼編譯為目標處理器需要的形式,并下載到目標處理器上運行,以防止編譯過程引入新的錯誤。PIL測試也是等效性測試,其方式與SIL類似,不同之處是編譯好的算法運行在目標處理器上,而SIL測試是在算法開發(fā)環(huán)境進行的。
4. HIL(Hardware in the Loop)硬件在環(huán)測試
HIL測試通常在開發(fā)出完整的控制器后進行,有時被控對象(如整車)還未完成開發(fā),或者使用真實被控對象進行測試太危險或成本高。在HIL測試中,采用真實控制控制器和虛擬被控對象,以進行全面的功能驗證和性能評估。HIL測試尤其適用于那些對實時響應、外部設(shè)備交互要求嚴苛的嵌入式系統(tǒng),它能真實反映出軟件在實際運行條件下的表現(xiàn),有效暴露系統(tǒng)在軟硬件集成層面可能出現(xiàn)的問題。
這四種測試方法各自的特點如下:
◆ MIL關(guān)注模型層面的功能實現(xiàn)及測試覆蓋度情況。
◆ SIL關(guān)注的是生成的代碼與模型間的一致性。
◆ PIL關(guān)注的是代碼在目標處理器上的運行情況。
◆ HIL關(guān)注的是軟硬件集成后的整體系統(tǒng)表現(xiàn)。
05.
軟件單元測試覆蓋率
ISO26262 part6的表9—軟件單元級別的結(jié)構(gòu)覆蓋度指標如下表所示:
1. 語句覆蓋:它關(guān)注的是程序中每個可執(zhí)行語句是否至少被執(zhí)行過一次。這是代碼覆蓋率分析中最基本的形式,其目的是確保測試用例能夠覆蓋到程序中的所有代碼行。
由于其簡單性,語句覆蓋通常容易實現(xiàn)和維護。語句覆蓋并不保證程序的邏輯路徑被完全測試。例如,它不能保證所有的條件分支都被測試,或者所有的循環(huán)邊界都被觸及。為了達到100%的語句覆蓋,測試用例需要設(shè)計得能夠觸發(fā)程序中的每一個語句。語句覆蓋并不保證程序的質(zhì)量,因為即使所有語句都被執(zhí)行,也可能存在邏輯錯誤未被發(fā)現(xiàn)。
例:
2. 分支覆蓋:它要求測試用例能夠覆蓋程序中所有可能的分支路徑。分支覆蓋關(guān)注的是程序中的控制流,特別是條件語句(如 if, else, switch 等)的真假分支是否都被執(zhí)行過至少一次。
分支覆蓋是路徑覆蓋的一個子集,它確保了程序中的每個分支都被測試。通過確保每個分支都被測試,分支覆蓋有助于發(fā)現(xiàn)那些只在特定條件下才會觸發(fā)的缺陷。為了達到分支覆蓋,測試用例需要設(shè)計得能夠觸發(fā)每個分支的真假條件。分支覆蓋比語句覆蓋更嚴格,因為它要求測試每個條件的真假分支。分支覆蓋并不保證所有可能的執(zhí)行路徑都被測試,特別是當存在多個條件時。
3. MC/DC覆蓋:要求測試用例能夠覆蓋程序中所有可能的條件組合,并且每個條件都能獨立影響決策的結(jié)果。這是一種高級的白盒測試技術(shù),主要用于驗證軟件中的邏輯條件和決策路徑。
MC/DC要求每個條件在決策中都能獨立地影響決策的結(jié)果。這意味著,當改變一個條件的值時,決策的結(jié)果也會隨之改變,而其他條件保持不變。MC/DC覆蓋了所有條件的所有可能結(jié)果,以及每個決策的所有可能結(jié)果。實現(xiàn)MC/DC可能需要更多的測試用例,因為每個條件都需要獨立地影響決策的結(jié)果。
MC/DC與其他覆蓋標準的區(qū)別:
與語句覆蓋的區(qū)別:語句覆蓋關(guān)注于代碼的行,而MC/DC關(guān)注于條件和決策的獨立影響。
與分支覆蓋的區(qū)別:
分支覆蓋要求測試每個分支的真假路徑,而MC/DC進一步要求每個條件都能獨立地影響決策的結(jié)果。
讓我們通過一個具體的C語言函數(shù)例子來展示如何為語句覆蓋、分支覆蓋和MC/DC覆蓋設(shè)計測試用例。假設(shè)我們有以下函數(shù):
語句覆蓋測試用例:
語句覆蓋要求覆蓋函數(shù)中的每個語句至少一次。我們需要以下測試用例:
1. get_value(1,1)——覆蓋語句1(x和y都大于0)。
2. get_value(1,-1)——覆蓋語句2(x大于0,y小于等于0)。
3. get_value(-1,1)——覆蓋語句3(x小于等于0,y大于0)。
分支覆蓋測試用例:
分支覆蓋要求覆蓋每個條件的每個可能分支。我們需要以下測試用例:
1. get_value(1,1)——條件1真,條件2真。
2. get_value(1,-1)——條件1真,條件2假。
3. get_value(-1,1)——條件1假,條件2不可達(因為我們已經(jīng)知道x小于等于0,所以不會檢查y)。
4. get_value(-1,-1)——條件1假,條件2假。
MC/DC覆蓋測試用例:
MC/DC覆蓋要求每個條件在決策中都能獨立地影響決策的結(jié)果。我們需要以下測試用例:
1. get_value(1,1)——條件1真,條件2真,覆蓋語句1。
2. get_value(1,-1)——條件1真,條件2假,覆蓋語句2。
3. get_value(-1,1)——條件1假,條件2不可達,覆蓋語句3。
4. get_value(-1,-1)——條件1假,條件2假,再次覆蓋語句3,但這次是為了證明條件1的獨立影響。
為了滿足MC/DC的要求,我們需要確保改變?nèi)魏我粋€條件的值都能獨立地影響函數(shù)的返回值。這意味著我們需要額外的測試用例來證明條件1和條件2可以獨立地影響決策:
5. get_value(2, 0)——條件1真,條件2真,但y的值改變不影響決策,因為x大于0。
6. get_value(0, 1)——條件1假,條件2真,但x的值改變不影響決策,因為x不大于0。
通過這些測試用例,我們可以看到MC/DC覆蓋比語句覆蓋和分支覆蓋更為嚴格,它要求每個條件都能獨立地影響決策的結(jié)果。這有助于發(fā)現(xiàn)那些可能在條件組合中被隱藏的錯誤。
許多現(xiàn)代的集成開發(fā)環(huán)境(IDE)和測試工具都支持語句覆蓋和分支覆蓋,可以自動收集和報告覆蓋率數(shù)據(jù)。一些自動化測試工具可以輔助實現(xiàn)MC/DC,通過分析代碼邏輯并生成相應的測試用例。
作者
邊俊
磐時創(chuàng)始人/首席安全專家
汽車安全社區(qū)SASETECH發(fā)起人;智能網(wǎng)聯(lián)預期功能安全工作組核心成員;國內(nèi)最早從事汽車功能安全、預期功能安全的專家之一
-
測試
+關(guān)注
關(guān)注
8文章
5898瀏覽量
130257 -
軟件
+關(guān)注
關(guān)注
69文章
5240瀏覽量
90318 -
汽車安全
+關(guān)注
關(guān)注
4文章
319瀏覽量
35296
發(fā)布評論請先 登錄
MCU進行單元測試的方法
單元測試/集成測試自動化工具--WinAMS
如何提高嵌入式軟件單元測試效率
什么是單元測試_單元測試的目的是什么
java單元測試的好處
什么是單元測試,為什么要做單元測試
MCU如何進行單元測試

評論