測(cè)試是一個(gè)非常基礎(chǔ)的概念,這種基礎(chǔ)讓大家可以隨意在它前面添加各種定語。
盡管這種添加的背后多數(shù)是不同的分類維度,但讓測(cè)試本身成為了繁雜概念的集合,這也讓我們總有種無法把握的煩躁感。
單元測(cè)試就是這堆讓人煩躁的繁雜概念之一。
1
3種軟件測(cè)試分類及單元測(cè)試的定義
如前所述,軟件測(cè)試的分類維度非常多,我們僅從以下常見的3種方式闡釋:
按是否執(zhí)行軟件分類:靜態(tài)測(cè)試和動(dòng)態(tài)測(cè)試,單元測(cè)試橫跨二者。
按是否關(guān)注內(nèi)部代碼分類:白盒測(cè)試和黑盒測(cè)試,單元測(cè)試屬于白盒測(cè)試。
按汽車軟件集成層次分類:從單元測(cè)試到整車驗(yàn)收有各級(jí)測(cè)試(參考《汽車軟件集成的5個(gè)層次》),單元測(cè)試屬于最低一個(gè)層級(jí)。
當(dāng)我們?nèi)ゾW(wǎng)上搜索單元測(cè)試的定義時(shí),往往會(huì)看到類似這樣的說法,“單元測(cè)試是指對(duì)軟件中的最小可測(cè)單元進(jìn)行測(cè)試”。
但這個(gè)描述只能是一個(gè)正確的定義,仍然很難把握。什么叫最小可測(cè)單元?一個(gè)函數(shù)?一個(gè)類?一個(gè).c?還是一個(gè)功能模塊?
爭(zhēng)論一直存在。
擱置爭(zhēng)議,我們只看汽車行業(yè)。按照慣例或標(biāo)準(zhǔn),廣義上,可以把軟件集成測(cè)試以下所有測(cè)試都看作是單元測(cè)試。
2
單元測(cè)試的4種類型
進(jìn)一步地,在汽車軟件領(lǐng)域,我們可以將單元測(cè)試細(xì)分為代碼評(píng)審、靜態(tài)分析、單元(代碼功能)測(cè)試和單元(代碼覆蓋度)測(cè)試。
前兩種屬于靜態(tài)測(cè)試,后兩種屬于動(dòng)態(tài)測(cè)試。
2.1 代碼評(píng)審
根據(jù)形式或正式程度上的差異,代碼評(píng)審會(huì)分成很多名目,比如:
走查(Walk Through)
同行評(píng)審(Peer Review)
代碼評(píng)審(Code Revew)
結(jié)對(duì)編程(Pair Programming)
代碼審查(Code Inspection)
但簡單來說,代碼評(píng)審就是人看,一個(gè)或一組人面對(duì)可閱讀的源代碼(有時(shí)也需要結(jié)合需求或軟件文檔),進(jìn)行隨意的或正式會(huì)議下的檢查。
可能會(huì)識(shí)別出如下的一些問題:
無注釋的代碼
不可達(dá)的條件路徑
太復(fù)雜的循環(huán)嵌套
無返回值的分支
未初始化的變量
空指針的引用
不規(guī)范的命名規(guī)則
......
理論上,對(duì)于手寫代碼的合理性與正確性,他人及更有經(jīng)驗(yàn)的他人去檢查一遍,有一定的意義,甚至某些案例下,會(huì)勝過后期測(cè)試。
比如,開發(fā)調(diào)用了名稱相似的變量,這種錯(cuò)誤可能在流到很后期才會(huì)被探測(cè)到。
實(shí)際上,代碼評(píng)審也同其他評(píng)審類似,都是無奈為之而又常常流于形式的手段。
解決這類問題的方法不外乎3個(gè):
? 用更負(fù)責(zé)且有經(jīng)驗(yàn)的人
?提升形式的強(qiáng)制性
? 積累充足的Checklist
其中,在下一節(jié)靜態(tài)分析工具使用后,人的經(jīng)驗(yàn)就成為了代碼評(píng)審存在的最大意義。
總之,代碼評(píng)審不算是典型的測(cè)試,但作為編碼后的第一道屏障,仍然有必要存在。
2.2 靜態(tài)分析
相較于人工代碼評(píng)審的低效,靜態(tài)分析是依賴于諸如Parasoft、Polyspace、Coverity等工具的自動(dòng)化分析。
因?yàn)椴恍枰獔?zhí)行軟件,所以靜態(tài)分析仍然不需要二進(jìn)制代碼或可執(zhí)行程序。
靜態(tài)分析工具通常主要支持以下兩種分析類型:
語法分析:主要檢查是否符合編程語言的語法規(guī)則,如MISRA C。
代碼路徑分析:主要包括控制流分析(如語句條件分支、循環(huán)迭代次數(shù))、數(shù)據(jù)流分析(如變量值的傳遞)、代碼復(fù)雜性(如圈復(fù)雜度、路徑長度)、依賴關(guān)系(如函數(shù)之間的調(diào)用、模塊之間的依賴)等。
當(dāng)對(duì)部分或全部代碼進(jìn)行靜態(tài)掃描后,會(huì)得到基于內(nèi)置規(guī)則集的判定結(jié)果,一般會(huì)包含分等級(jí)的規(guī)則違反情況。
如MISRA C: 2012分為強(qiáng)制(Mandatory)、必要(Required)和建議(Advisory)。
通常,強(qiáng)制項(xiàng)必修,必要項(xiàng)需要進(jìn)行評(píng)審。但有時(shí)候,涉及到第三方標(biāo)準(zhǔn)庫時(shí),就無法按照這個(gè)規(guī)則執(zhí)行了,具體還是要看產(chǎn)品類型(如是否涉及信息安全)和公司要求。
此外,由于編譯器基本也都具備類似的代碼檢查作用,靜態(tài)分析工具也可以理解為編譯器的擴(kuò)展。
因此,我們也會(huì)把編譯器警告或錯(cuò)誤作為要處理的條目。
2.3單元(代碼功能)測(cè)試
這部分測(cè)試的源頭是軟件詳細(xì)設(shè)計(jì),測(cè)試重點(diǎn)從代碼寫得漂不漂亮轉(zhuǎn)移到代碼寫得有沒有用,也就是是不是符合了設(shè)計(jì)。
汽車軟件用例的設(shè)計(jì),一般有如下兩種密切相關(guān)的方法:
2.3.1 等價(jià)類劃分法
等價(jià)類劃分是將軟件單元的輸入數(shù)據(jù)劃分為等價(jià)數(shù)據(jù)(即可以導(dǎo)致相同的輸出)的分區(qū),而后用測(cè)試用例去至少覆蓋每個(gè)分區(qū)一次。
其背后的訴求是,通過劃分輸入數(shù)據(jù)的類別來限定測(cè)試用例的數(shù)量。
舉一個(gè)例子。
一個(gè)函數(shù)輸入的范圍是1~100,如果要窮舉式測(cè)試,我們需要為輸入參數(shù)編寫100個(gè)測(cè)試用例。
而使用等價(jià)類劃分法的話,測(cè)試用例就可以分為三類:
有效(1~100)
以下無效(例如0)
以上無效(>100)
于是,用例也就可以縮減為3個(gè)。
可能有人很快會(huì)有疑問,按照等價(jià)輸入數(shù)據(jù)進(jìn)行測(cè)試,會(huì)不會(huì)有遺漏呢?
沒錯(cuò),尤其是邊界值處很容易出錯(cuò)。這就是第二個(gè)方法要解決的問題。
2.3.2 邊界值法
仍然以上一個(gè)案例展開。
使用邊界值法的話,我們可為等價(jià)類劃分法定義的測(cè)試用例作如下補(bǔ)充:
剛好在邊界(1,100)
剛好在邊界以下(0,99)
剛剛越過邊界(2,101)
經(jīng)過兩種方法的結(jié)合,缺陷發(fā)現(xiàn)的能力會(huì)進(jìn)一步提高。
2.4單元(代碼覆蓋度)測(cè)試
單元(代碼功能)測(cè)試完成后,夠了嗎?不夠。
我們沒測(cè)出bug,代表的不是軟件沒bug,而是沒測(cè)夠。
沒測(cè)夠的典型表現(xiàn)是測(cè)試用例對(duì)代碼的覆蓋程度不足,這就是本節(jié)要處理的問題。
主要的代碼覆蓋度測(cè)試類型包括以下4種,嚴(yán)格程度從上到下依次增強(qiáng):
語句覆蓋(Statement Coverage):這是最基本的覆蓋度類型,它確保每個(gè)代碼語句至少執(zhí)行一次,100%的語句覆蓋率可以保證沒有死代碼,屬于入門級(jí)別的測(cè)試。
分支覆蓋(Branch Coverage):分支覆蓋確保每個(gè)分支語句(通常是if語句)都被覆蓋到,即每個(gè)分支的真和假兩種情況都被測(cè)試到,有助于揭示一些邏輯錯(cuò)誤,如if a and b then...,用例為a真+b真(分支為真)、a真+b假(分支為假,與其他條件組合等價(jià))即可100%。
條件覆蓋(Condition Coverage):條件覆蓋要求每個(gè)分支語句的每個(gè)條件都被覆蓋,即每個(gè)條件的真和假兩種情況都被測(cè)試到,它比分支覆蓋更為嚴(yán)格,因?yàn)樗鼤?huì)關(guān)注條件的組合覆蓋,如if a and b then...,用例為a真+b真、a真+b假、a假+b真、a假+b假才可100%。
修改條件/判定組合覆蓋(Modified Condition/Decision Combination Coverage):這一級(jí)別的覆蓋要求同時(shí)滿足條件覆蓋和判定覆蓋,以確保條件和判定之間的組合覆蓋,是一種更加嚴(yán)格的覆蓋度測(cè)試。
不同的項(xiàng)目和產(chǎn)品可能需要不同類型的代碼覆蓋度測(cè)試。
通常,基礎(chǔ)的覆蓋度(如語句覆蓋和分支覆蓋)是必要的起點(diǎn),而在需要更高可靠性和安全性的項(xiàng)目中,可能會(huì)選擇更嚴(yán)格的MC/DC覆蓋度,比如,涉及ASIL D的模塊。
3
單元測(cè)試意義的思考
說意義的話,我們可以很快說出一大堆,bug提前暴露、提升軟件質(zhì)量、軟件更加健壯、利于重構(gòu)、清除技術(shù)債務(wù)、積累組織資產(chǎn)......
問題在于,在不好言明的價(jià)值和巨大的交付壓力之下,單元測(cè)試太容易被權(quán)衡掉了,誰還沒有個(gè)意義呢?
實(shí)際上,管中窺豹,對(duì)這類重要但不緊急事情的意義的探討會(huì)折射出很多面的信息,比如下面這個(gè)算式。
自動(dòng)化的程度+對(duì)軟件的理解+產(chǎn)品的競(jìng)爭(zhēng)力+公司的文化+行業(yè)的生態(tài)=單元測(cè)試的意義
4
全文小結(jié)
本文主要在講單元測(cè)試的一些基本概念和應(yīng)用場(chǎng)景。
首先,從是否執(zhí)行軟件、是否關(guān)注內(nèi)部代碼和汽車軟件分層集成這3個(gè)方面解釋了單元測(cè)試的特點(diǎn)。進(jìn)而,引申出汽車軟件單元測(cè)試的概念。
接著,將單元測(cè)試細(xì)分為代碼評(píng)審、靜態(tài)分析、代碼功能測(cè)試、代碼覆蓋度測(cè)試,并分別進(jìn)行了描述。
由于單元測(cè)試離客戶需求太遠(yuǎn),往往被務(wù)實(shí)的我們忽略,如何看待其價(jià)值需要探討,第3小節(jié)對(duì)此做了簡單分析。
5
寫在最后
不只是單元測(cè)試,軟件大舉進(jìn)入汽車行業(yè)的過程中,未來無形不可見和當(dāng)下有形可見的價(jià)值沖突持續(xù)在上演。
如何把握向左還是向右的分寸始終是一個(gè)巨大的決策考驗(yàn)。
-
汽車行業(yè)
+關(guān)注
關(guān)注
0文章
292瀏覽量
15323 -
代碼
+關(guān)注
關(guān)注
30文章
4697瀏覽量
68085 -
汽車軟件
+關(guān)注
關(guān)注
0文章
86瀏覽量
3145
原文標(biāo)題:汽車軟件單元測(cè)試的要點(diǎn)與意義
文章出處:【微信號(hào):談思實(shí)驗(yàn)室,微信公眾號(hào):談思實(shí)驗(yàn)室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論