單元測試:驅動模塊和樁模塊區別概念


傳統的單元測試包括了驅動模塊(driver) 和樁模塊(stub)。驅動模塊的目的很單純,就是為了訪問類庫的屬性和方法,來檢測類庫的功能是否正確;
驅動模塊
驅動模塊是用來模擬被測試模塊的上一級模塊,相當於被測模塊的主程序。它接收數據,將相關數據傳送給被測模塊,啟用被測模塊,並打印出相應的結果。
驅動模塊(Driver)可以通過模擬一系列用戶操作行為,比如選擇用戶界面上的某一個選項或者按下某個按鈕等,自動調用被測試模塊中的函數。驅動模塊(Driver)設置,使對模塊的測試不必與用戶界面真正交互。
樁模塊
樁模塊是指模擬被測試的模塊所調用的模塊,而不是軟件產品的組成的部分。主模塊作為驅動模塊,與之直接相連的模塊用樁模塊代替。在集成測試前要為被測模塊編制一些模擬其下級模塊功能的“替身”模塊,以代替被測模塊的接口,接受或傳遞被測模塊的數據,這些專供測試用的“假”模塊稱為被測模塊的樁模塊。
如果被測試的單元模塊需要調用其他模塊中的功能或者函數(method),我們就應該設計一個和被調用模塊名稱相同的樁模塊來模擬被調用模塊。這個樁模塊本身不執行任何功能僅在被調用時返回靜態值來模擬被調用模塊的行為。舉例說明:如果被測試單元中需要調用另一個模塊customer的函數 getCustomerAddress(customerID: Integer),這個函數應該查詢數據庫后返回某一個客戶的地址。我們設計的同名樁模塊(Stub)中的同名函數並沒有真正對數據庫進行查詢而僅模擬了這個行為,直接返回了一個靜態的地址例如"123 Newton Street"。樁模塊的設置使得單元測試的進行成為一個相對獨立且簡單的過程。


總結:
樁模塊的使命除了使得程序能夠編譯通過之外,還需要模擬返回被代替的模塊的各種可能返回值(什么時候返回什么值需要根據測試用例的情況來決定)。
驅動模塊的使命就是根據測試用例的設計去調用被測試模塊,並且判斷被測試模塊的返回值是否與測試用例的預期結果相符

單元測試:

在底層進行的對類/方法內部邏輯的測試叫做單元測試,也叫做模塊測試。當單元測試的bug修復后,再把模塊組合在一起構成子系統測試,這就是集成測試。集成測試的bug修復后各個子系統模塊再組成整體業務流程的整套測試,這個過程叫做系統測試。

驅動模塊:
驅動模塊是用來模擬被測模塊的上一級模塊,相當於被測模塊的主程序。它接收數據並將相關數據傳送給被測模塊,啟用被測模塊並打印出相應結果。驅動模塊的目的很單純,就是訪問類庫的屬性和方法來確定類庫是否正確。

樁模塊:
樁模塊是模擬被測試模塊所調用的模塊,而不是軟件產品的組成部分。主程序作為驅動模塊,與之直接相連的模塊是樁模塊,也稱為“替身模塊”。樁模塊本身不執行任何功能,只在它作為替身被調用時返回靜態值。

樁模塊和驅動模塊(以C語言為例):

  很多人對樁模塊和驅動模塊的概念會搞不清楚,那么下面來介紹這兩個概念:

  模塊結構實例圖:

  假設現在項目組把任務分給了7個人,每個人負責實現一個模塊。你負責的是B模塊,你很優秀,第一個完成了編碼工作,現在需要開展單元測試工作,先分析結構圖:

  1、由於B模塊不是最頂層模塊,所以它一定不包含main函數(A模塊包含main函數),也就不能獨立運行。

  2、B模塊調用了D模塊和E模塊,而目前D模塊和E模塊都還沒有開發好,那么想讓B模塊通過編譯器的編譯也是不可能的。

  那么怎樣才能測試B模塊呢?需要做:

  1、寫兩個模塊Sd和Se分別代替D模塊和E模塊(函數名、返回值、傳遞的參數相同),這樣B模塊就可以通過編譯了。Sd模塊和Se模塊就是樁模塊。

  2、寫一個模塊Da用來代替A模塊,里面包含main函數,可以在main函數中調用B模塊,讓B模塊運行起來。Da模塊就是驅動模塊。

  知識點:

  樁模塊的使命除了使得程序能夠編譯通過之外,還需要模擬返回被代替的模塊的各種可能返回值(什么時候返回什么值需要根據測試用例的情況來決定)。

  驅動模塊的使命就是根據測試用例的設計去調用被測試模塊,並且判斷被測試模塊的返回值是否與測試用例的預期結果相符

驅動模塊是調用被測對象,樁是被測對象調用的虛擬塊

虛擬塊也是有測試人員寫的一個模塊,就是那個所謂的樁

驅動模塊是為了驅動被測模塊而編寫的模擬塊,而樁模塊相當於被測模塊要調用的塊的虛擬。

驅動模塊主要完成以下事情:

1、接受測試輸入;

2、對輸入進行判斷;

3、將輸入傳給被測單元,驅動被測單元執行;

4、接受被測單元執行結果,並對結果進行判斷;

5、將判斷結果作為用例執行結果輸出測試報告。

被測單元用什么語言,驅動就用什么語言寫。

總而言之,寫驅動和樁不需要太高深編程知識。如果有模板或框架作為參考的話,差不多就成了一個體力活。

一個簡單例子:

 

  1.  
    /*被測程序*/
  2.  
    int Fun(int in)
  3.  
    {
  4.  
    if (in >= 0)
  5.  
    {
  6.  
    return 1;
  7.  
    }
  8.  
    else
  9.  
    {
  10.  
    return -1;
  11.  
    }
  12.  
    }

那么通過TCL進行擴展指令編寫時,針對該被測函數,驅動如下:

/*用戶自己擴展的用戶指令,用來驅動被測函數*/

 

  1.  
    int Ex_TestFun(ClientData clientData,Tcl_Interp * interp,int argc, char* argv[])
  2.  
    {
  3.  
    int i;
  4.  
    int ret,iExceptedRet;
  5.  
    //打開測試結果記錄文件
  6.  
    FILE * out;
  7.  
    out = fopen( "D:\\result.txt","a");
  8.  
    //第一步:檢查用戶輸入參數個數是否正確
  9.  
    if (3 != argc)
  10.  
    {
  11.  
    fputs("Parameters error",out);
  12.  
    fflush(out);
  13.  
    return TCL_ERROR;
  14.  
    }
  15.  
    //第二步:取出用戶輸入參數
  16.  
    if (TCL_OK != Tcl_GetInt(interp,argv[1],&i))
  17.  
    {
  18.  
    return TCL_ERROR;
  19.  
    }
  20.  
    if (TCL_OK != Tcl_GetInt(interp,argv[2],&iExceptedRet))
  21.  
    {
  22.  
    return TCL_ERROR;
  23.  
    }
  24.  
    //第三步:將參數傳遞給被測函數
  25.  
    ret = Fun(i);
  26.  
    //第四步:將被測函數執行結果和輸入的期望結果進行比較,根據比較結果作為用例執行結果輸出到測試報告中
  27.  
    if (ret != iExceptedRet)
  28.  
    {
  29.  
    fputs("test fail",out);
  30.  
    fflush(out);
  31.  
    }
  32.  
    else
  33.  
    {
  34.  
    fputs("test success",out);
  35.  
    fflush(out);
  36.  
    }
  37.  
    return TCL_OK;
  38.  
    }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM