C++組件測試及應(yīng)用 — 基于Tessy的測試技術(shù)漫談
編者按:隨著行業(yè)軟件的安全性關(guān)注度遞增,在產(chǎn)品測試初期開展全面單元/集成測試逐漸成為了開發(fā)測試過程中關(guān)鍵環(huán)節(jié),它將有助于盡早發(fā)現(xiàn)隱患,降低開發(fā)成本以及更加充分的功能驗證。ISO26262及ASPICE中同樣對單元/集成測試的實施提出了相應(yīng)的要求。針對代碼的單元測試,要求對程序中每個單元開展功能測試,而幾個層次結(jié)構(gòu)的單元組合,如果有功能,也可以把該單元組合稱為模塊。對于集成測試,要求針對具備功能的模塊進(jìn)行測試,此處具有功能的模塊,我們可以稱為組件,并且通過增式測試的方式逐漸實現(xiàn)各組件的組合測試,因此,集成測試也可以看作是針對這些組件的功能和組件組合功能進(jìn)行綜合驗證的過程。
此文章來源于Tessy原廠Hitex于11月底發(fā)布的白皮書《Component Testing of Test Objects in C++ ——Writing scenarios for integration testing in TESSY》。
1 從單元到組件
? 1.1測試對象的類型
我們將基于測試對象類型討論“單元測試”、“模塊測試”、“集成測試”和“組件測試”,側(cè)重介紹時序的組件測試(假設(shè)軟件是C或者C++開發(fā))。
? 1.1.1單元
單個函數(shù)是C語言程序中的合理測試對象,通常被認(rèn)為是一個單元。如果編程語言是C++,那么將方法視為一個單元。
單元測試是基于被測單元接口(即輸入和輸出)開展的功能驗證。開展單元測試時,會實際編譯執(zhí)行被測程序,如果被測試的“單元”調(diào)用了其他函數(shù),可以通過創(chuàng)建樁函數(shù)對調(diào)用的函數(shù)進(jìn)行替換以保證測試的順利進(jìn)行,提高測試效率。
? 1.1.2 具有層次結(jié)構(gòu)的單元
具有層次結(jié)構(gòu)的多個單元可以以一種類似于單個單元測試的方式開展,將頂層單元作為測試對象,關(guān)注整體功能,被調(diào)用單元看作內(nèi)部實現(xiàn),針對整體的輸入輸出開展測試。

Fig.1 將頂層單元作為測試對象的單元層次結(jié)構(gòu)
從技術(shù)角度,這可以通過不使用樁函數(shù)替換被調(diào)用單元實現(xiàn)。仍可以像上面那樣將其視為單元測試,只不過是更大的單元。
這也可以看作是單元層次結(jié)構(gòu)中的集成測試,因為從某種程度上,它們能正確地一起工作才能通過測試。這樣的單元層次結(jié)構(gòu)也能被稱為模塊(Module),但是我不想用這個術(shù)語,因為這可能會與C/C++程序的源模塊概念混淆。(一個C源模塊不能直接作為模塊測試對象,因為它是依照語法定義的,而用于模塊測試的module通常是按照語義定義的。)
多個單元層次結(jié)構(gòu)的測試在技術(shù)上與單個單元測試非常類似,由于當(dāng)前文檔主題是組件測試,因此進(jìn)一步討論的是功能層次結(jié)構(gòu)的測試。
? 1.1.3 相互作用且無時序關(guān)系的單元
與單元層次結(jié)構(gòu)相反,在接下來,我們認(rèn)為單元之間不一定具有調(diào)用關(guān)系,然而,我們假設(shè)這些單元相互協(xié)同工作,例如操作公共數(shù)據(jù)以實現(xiàn)一個共同目標(biāo)。
眾所周知的抽象數(shù)據(jù)類型“棧(stack)”,及其push和pop操作就是一個很淺顯易明的例子。pop和push操作的測試是單元測試,但是仍需要進(jìn)行集成測試。集成測試由一系列pop和push操作組成。該測試用例的輸入由棧的初始內(nèi)容和push操作的參數(shù)值組成,結(jié)果是pop操作的返回值和棧的狀態(tài)。如果push和pop操作可能導(dǎo)致對單元的額外調(diào)用,例如對棧溢出/下溢的錯誤處理單元的調(diào)用,這些調(diào)用也屬于集成測試用例的預(yù)期結(jié)果。
Fig.2 對于抽象數(shù)據(jù)類型“棧(stack)”的push和pop操作,單元測試是不充分的
“模塊(Module)”這個術(shù)語可能更適合于這樣一個協(xié)作單元集合,但我更喜歡用“組件(component)”這個術(shù)語,因為它的含義與C/C++源模塊不一樣。
Fig.3 組件的內(nèi)部結(jié)構(gòu)及其與外部的接口
“組件”內(nèi)含的“單元”中,至少有一個具備從組件外部調(diào)用以驅(qū)動組件的功能。通常一個組件的幾個單元來自外部調(diào)用,我們稱這些單元為“組件函數(shù)”或“組件單元”。對一個組件的測試不再由(一個或多個)對單個單元的調(diào)用(如上面兩部分所述)組成,而是由對(不同的)組件單元的一系列調(diào)用組成。對組件單元的調(diào)用將激活組件,與單個單元測試一樣,組件的測試用例也包括輸入和輸出數(shù)據(jù)(組件的變量和被調(diào)用組件單元的參數(shù))。組件可能具有內(nèi)部單元,這些單元不能從組件外部調(diào)用,只能通過組件內(nèi)部的函數(shù)調(diào)用獲取。
內(nèi)部單元所做的工作(如果有的話)與組件測試無關(guān),因此組件測試中,是將整個組件看作一個黑盒。然而,與組件測試結(jié)果相關(guān)的是從組件內(nèi)部到其他組件中(可調(diào)用的)單元的調(diào)用序列。這涉及到調(diào)用的數(shù)量、調(diào)用的順序和調(diào)用傳遞給其他組件的參數(shù)。
很顯然,組件中單元的功能以及它們之間的接口大部分情況下是通過組件測試來實現(xiàn)驗證。因此,組件測試可以看作是對組件中單元的集成測試。

? 1.1.4 相互作用且有時序關(guān)系的單元
在上一節(jié)中,時序不是重點,無論是組件的激發(fā)調(diào)用時長,還是組件的激發(fā)調(diào)用與另一個組件的結(jié)果調(diào)用之間的時長。然而,這是一個檢查收到激發(fā)調(diào)用后響應(yīng)是否足夠快的重要測試,即在給定的時間范圍內(nèi)。
為了能夠在模擬環(huán)境中測試組件的時序行為,需要有一個模擬的時間基數(shù)。這意味著組件內(nèi)部的某個單元在已知的等距時間內(nèi)被調(diào)用(例如每10ms),通常組件在實時操作系統(tǒng)(RTOS)的控制下執(zhí)行并使用time-slicing(例如OSEK)就是這種情況,但一個簡單的中斷驅(qū)動應(yīng)用程序通常也符合這種要求。
對該單元的調(diào)用代表組件的“心跳(heartbeat)”,它們?yōu)闇y試組件的時序行為提供了一個(模擬的)時間參考。心跳函數(shù)通常被稱為“handler function”或“work task”或簡單稱為“tick”。
Fig.4 如果心跳函數(shù)存在,則可以測試時序行為
2 C++棧的例子
? 2.1 介紹
正如前面所介紹的,抽象數(shù)據(jù)類型棧是一個典型的例子,在Tessy中進(jìn)行集成測試需要使用Tessy的組件測試功能(在場景編輯器透視圖中可以訪問)來完成。而且,push和pop不相互調(diào)用,而是在公共數(shù)據(jù)(棧)上通信,因此,單純的單元測試技術(shù)手段是不適用的,因為它們要求單元有一個單一的入口點,即單元測試側(cè)重測試一個單一函數(shù)/方法。
Fig.5 stack.push和stack.pop不互相調(diào)用,需要集成測試
? 2.2 測試對象源代碼
Fig.6 測試對象的源碼(stack.cpp)
注:源代碼后三行不屬于堆棧的實現(xiàn),而是Tessy所要求的,由于使用了#ifdef,所以tick()函數(shù)只在源文件被Tessy處理時才出現(xiàn)。
? 2.3 Tessy準(zhǔn)備工作
測試環(huán)境選擇GCC(C++),測試類型選擇Component,導(dǎo)入代碼。
Fig.7 選擇編譯環(huán)境
? 2.4 接口設(shè)置
新建一個變量my_stack作為實例化的對象。
Fig.8 接口設(shè)置
? 2.5 測試用例設(shè)計和執(zhí)行
創(chuàng)建測試用例:驗證入棧出棧操作。
Fig.9 場景1的設(shè)計和執(zhí)行結(jié)果
創(chuàng)建第二個測試用例:該用例目的是驗證棧下溢情況下的功能實現(xiàn)。
在Edit Test Execution Settings界面勾選Test Cases Separately分別執(zhí)行兩個場景,場景及結(jié)果如下圖所示。
Fig.10 場景2的設(shè)計和執(zhí)行結(jié)果
在SCE的用例設(shè)計界面中,針對指針的操作如下:為指針*arr創(chuàng)建一個對象,指定其為一個長度為4的數(shù)組;指向這個目標(biāo)的指針由Tessy分配給對象my_stack中的變量arr,也就是說,分配的內(nèi)存代替了由測試對象的構(gòu)造函數(shù)分配的內(nèi)存,由于此前將指向指針對象的接口設(shè)置為INOUT,所以該對象同時出現(xiàn)在Inputs和Outputs列項中。
Fig.11 為指針*arr創(chuàng)建一個對象
Fig.12 場景2 SCE執(zhí)行實際結(jié)果

經(jīng)緯恒潤
北京市海淀區(qū)知春路7號致真大廈D座6層
電話:010-64840808
郵箱:market_dept@hirain.com
網(wǎng)址:www.hirain.com
工程師必備
- 項目客服
- 培訓(xùn)客服
- 平臺客服
TOP




















