專利名稱:一種單元測試方法及其裝置的制作方法
技術領域:
本發明涉及軟件測試技術,特別是涉及一種單元測試方法及其裝置。
技術背景單元測試是軟件開發中質量保證的重要環節。單元測試包括以下幾個過程1) 、根據被測試模塊設計相應的測試模塊,測試模塊包括測試邏輯和測 試接口,測試邏輯需要構造被測試模塊的環境變量,設計測試用例,其中樁函 數是最主要的一種環境變量;而測試接口則是某一個測試的入口 ;2) 、修改被測試模塊,使被測試模塊可以引用測試模塊中的樁函數,通 常采用額外全局變量或者宏判別是否引用樁函數還是原來功能函數;3) 、編譯修改過的被測試模塊和測試模塊,生成可執行目標運行文件;4) 、運行目標可執行文件,啟動測試模塊;測試模塊通過不同的環境變 量組合(測試邏輯負責實現),完成對被測試模塊的測試;5) 、發布最后版本時,去掉測試模塊,修改被測試模塊,去除不必要的 針對測試的相關修改,重新編譯生成可執行文件。在上述過程中,需要兩次修改被測試模塊,第一次修改被測試模塊是為了 實現與測試模塊的關聯,傳統的方法是使用宏開關或控制變量,最后在測試完 畢后,需要再次修改被測試模塊,去除冗余的代碼,這樣帶來一些弊端1) 、采用靜態打樁或編譯期打樁,原有被測試模塊被修改,發布版本又 需要修改回來,單元測試結果的可信性、準確性都受到一定程度影響;2) 、被測試模塊的測試代碼和實際發布代碼混合在一起,給代碼版本管 理帶來不便。發明內容本發明所要解決的技術問題在于提供一種單元測試方法及其裝置,用于在不修改測試代碼時減小測試版本和發布版本的差異。為了實現上述目的,本發明提供了一種單元測試方法,用于實現對軟件系 統的單元測試,所述軟件系統包括被測試模塊,包括步驟一,根據所述被測試模塊設計生成相應的測試模塊,并對所述被測試 模塊、所述測試模塊進行編譯生成一執行文件;步驟二,運行所述執行文件,通過動態打樁完成所述被測試模塊與所述測 試模塊的掛接,執行測試;步驟三,修改編譯策略,去除對所述測試模塊的編譯,生成發布版本。 所述的單元測試方法,其中,所述步驟二中,由所述測試模塊的樁函數進行動態打樁完成所述被測試模塊與所述測試模塊的掛接。所述的單元測試方法,其中,所述步驟二中,所述樁函數根據一相應描述符的信息控制所述被測試模塊與所述測試模塊之間的跳轉條件和相互聯系,所述描述符的信息包括跳轉前后序言代碼、控制數據。所述的單元測試方法,其中,所述步驟二中,還包括在動態打樁時將所 述跳轉前后序言代碼、所述控制數據保存至所述描述符的歩驟。所述的單元測試方法,其中,所述步驟二中,還包括在進行動態打樁之 前,由被測試函數調用原功能函數,并將原功能函數的第一條指令替換為跳轉 指令,跳轉至所述樁函數的序言中的步驟。所述的單元測試方法,其中,所述步驟二中,由所述跳轉前后序言代碼完 成所述原功能函數向所述樁函數的序言的跳轉。所述的單元測試方法,其中,所述步驟二中,還包括由所述樁函數的序 言通過調用一條件函數判斷是執行所述樁函數還是返回至所述原功能函數繼續執行的步驟,若所述條件函數返回TRUE,則執行所述樁函數,否則返回至所述原功能函數繼續執行。所述的單元測試方法,其中,所述步驟二中,由所述條件函數根據由所述 樁函數的路徑控制函數得到的路徑參數判斷是執行所述樁函數還是返回至所 述原功能函數繼續執行。所述的單元測試方法,其中,所述步驟二中,還包括在所述執行測試完 成后,刪除打樁的步驟。為了實現上述目的,本發明提供了一種單元測試裝置,用于實現對軟件系統的單元測試,所述軟件系統包括被測試模塊,該裝置包括一生成編譯模塊,根據所述被測試模塊生成相應的測試模塊,并對所述被測試模塊、所述測試模塊進行編譯生成一執行文件;一動態打樁模塊,用于運行所述執行文件,通過動態打樁完成所述被測試模塊與所述測試模塊的掛接,執行測試;及一版本生成模塊,用于修改編譯策略,去除對所述測試模塊的編譯,生成 發布版本。相比于現有測試方法和裝置,本發明的主要優點在于1) 、保持待測試代碼的完整性運行期間代碼調用更換,不用因為名稱問題而修改待測試的代碼;保持測 試代碼的完整性;盡量減小測試版本和發布版本的行為的差異性。2) 、測試代碼集中管理測試代碼全部集中在一起,測試代碼的去留簡單易行,測試代碼便于統一 管理,版本具有更好的可控性。3) 、使集成測試更容易所有單元的單元測試代碼可以同時存在,在系統運行期間,可以根據需要 有選擇的進行部分或者全部單元的測試,使集成測試變得方便靈活。4) 、增強單元測試理論的實踐可用性實現了動態打樁功能后,可以將動態打樁工具集成到自動化測試環境,使 得單元測試更加便于使用。
圖1是本發明的樁函數調用關系及路徑; 圖2是本發明的單元測試流程圖; 圖3是本發明的bootstrap實現流程圖; 圖4是本發明的stub_prelude實現流程圖; 圖5是本發明的單元測試裝置結構圖。
具體實施方式
以下結合附圖和具體實施例對本發明進行詳細描述,但不作為對本發明的限定。下面以PowerPC CPU為例,詳細說明本發明動態打樁的實現方法,如圖1 所示,是本發明的樁函數調用關系及路徑,圖2描述了本發明的單元測試流程 圖;在說明實現方法之前,先說明一下使用方法,使用時分幾個步驟al)進行打樁,形式如下install一stub(B, stub—B, NULL);最后的參數NULL為條件函數—condition(),在執行樁函數之前,通過 —condition()函數來判斷是執行樁函數stub—B()還是回到原功能函數B()繼續執 行;a2)樁函數的路徑控制函數path—ctrlCpath),通過路徑參數jath,樁函數 stub—B()返回不同的值,同時缺省的—condition()函數可以根據此參數來判斷是否返回原功能函數BO;a3)執行被測試函數A();a4)判斷返回結果,確認測試結論;a5)刪除打樁動作remov^stub(stub—B)。運行時動態函數替換的一般原則是,被測試函數AO調用原功能函數B0, 原功能函數B()的第一條指令被替換為跳轉指令,跳轉到樁函數stub一B()的序 言stub_prelude中,然后在序言stub_prelude中調用描述符中的信息 —conditional()判斷是執行樁函數stub—B()還是繼續執行原功能函數B(),如果 —conditional()返回TRUE(非0),那么繼續運行樁函數代碼,如果—conditional) 返回FALSE (0),那么fallback運行原功能函數B()的代碼。增加—conditional() 主要是考慮到用戶可能有一些特別的需求,希望在特定情況下(如jath()無法 控制的特殊情況),能夠臨時回避樁函數stub一B()而調用原功能函數B()。在install—stub()之后,被測試函數A()調用原功能函數B()的情況變化,見 圖1所示。針對每個樁替換,都存在一個相應的描述符,在install—stub()時需要保存 如下信息到描述符bl) —orig函數地址(B地址),以便以后恢復指令;b2) —stub函數地址(stub—B地址),—stub函數地址之后將作為描述符數 組的關鍵字來使用;描述符數組是指所有測試模塊的樁函數stub—B()的描述符組成的數組。 b3) —conditional函數地址,供樁函數調用; b4)創建這個樁函數stub—B()的進程owner ID;b5) prelude序言的bootstrap部分,包括棧分配,保存lr、 r3;然后裝載 描述符結構地址到r3,并調用prdude();b6) fallback指令,包括被替換的指令(32bit),以及一條跳轉到—orig + 4 的指令,因為如果需要執行原功能函數B(),那么就要跳回原功能函數B()的 代碼段;fallback指令用于實現返回到原功能函數B()的跳轉,不是從樁函數stub—B() 跳轉至原功能函數B(),其通過條件判斷后返回原功能函數B(),由序言代碼 到原功能函數B的跳轉,樁函數stub—BG沒有執行;一orig是被替換的指令,在PowerPC中是一個32bit指令,該指令在構造 的fallback指令序列中已經被執行,所以繼續原功能函數B()的執行就是執行 —orig指令的下一條指令,即一orig + 4;b7)初始路徑設置,初始值為0。prelude—bootstrap()函數用于完成原功能函數B()至U stub_prelude調轉的接 續,每個描述符結構中都包括這部分代碼,具體作用是保存描述符本身、原功 能函數B()、樁函數stub一B()之間的對應關系,具體到PowerPC上來講,就是 記錄返回寄存器lr的內容,中間包括如下兩個調轉1、 原功能函數B()調轉到prelude—bootstrap()函數,在調轉中不影響原有 的lr, prdudej)ootstrap()函數記錄lr,其實記錄的是原有函數A()調用原功能 函數B()完成后應返回的地址;2、 從存在于描述符中的prelude—bootstrap()函數代碼調轉到stub_prelude, 這時候使用bl指令,也就是把描述符內部的一個地址裝載到了 lr寄存器, stubjrelude執行時候,可以根據lr判斷出當前使用的是哪個描述符。上述bl b7信息中,其中b5、 b6為跳轉前后序言代碼,其余為控制數據。 在對樁函數的調用關系及路徑進行描述后,進一步地,本發明的單元測試 方法包括以下過程步驟201,根據被測試模塊設計/設置相應的測試模塊;步驟202,通過不修改被測試模塊,對測試模塊和被測試模塊進行編譯,生成執行文件;步驟203,運行執行文件,通過動態打樁完成被測試模塊與測試模塊的掛 接,執行測試;該步驟中,被測試模塊與測試模塊的掛接即是進行install—stub(B, stub—B, NULL)調用后,修改了被測試模塊的功能函數的第一條指令為到測試模塊的跳 轉,測試模塊的樁函數就可以被調用到。步驟204、修改編譯策略,去掉對測試模塊的編譯,生成發布版本。與現有單元測試不同之處在于步驟202不修改被測試模塊源代碼,步驟 203執行測試時通過動態打樁完成被測試模塊與測試模塊的掛接。動態打樁是在運行期動態修改被測試模塊,改變被測試模塊與測試模塊之 間的調用關系,使得被測試模塊的函數在測試模塊的測試策略驅動下根據不同 的環境變量返回不同的結果,從而驗證被測試模塊在不同的環境參數組合下, 返回結果是否正常,從而達到單元測試的目的。進一步地,根據上述內容,動態打樁包括以下幾個主要部分cl)為了能夠有效控制被測試模塊和測試模塊之間的跳轉條件和相互聯 系,針對每個測試模塊中的樁函數stub—B()有對應的描述符,描述符包括跳轉 前后序言代碼及控制數據;c2)樁函數stub—B()根據路徑控制函數傳入的參數控制執行路徑,針對非 測試的路徑,會跳轉到原功能函數B()的內容;c3)測試完畢后可以動態恢復對原功能函數B()的修改,保持測試前運行 代碼的完整性。如圖3所示,是本發明的bootstrap實現流程圖,并結合圖1、 2,由于替 換了原功能函數B()的第一條指令為b prelude指令,因此當執行到 prelude—bootstrap()函數的第一條指令時,除了 pc值,其他寄存器以及棧的情 況較被測試函數A()都沒有變化,而被測試函數A()的調用信息也就丟失了, 因此,只能通過pc當前指令地址來取得樁函數的描述符的地址,即 prelude—bootstrap (PowerPC),該流程具體包括步驟301,開始;步驟302,分配棧楨,stwusp,-160(sp); 步驟303,保存r3, stwr3,32(sp);該步驟中,stwr3,32(sp訴于保存r3到堆棧,即保存lr (返回寄存器)的 內容;步驟304,保存lr, mflrr3, stw r3, 160(sp);該步驟中,mflrr3用于將lr調入r3; stwr3, 160(sp)用于保存r3到堆棧, 即保存lr (返回寄存器)的內容;步驟305,調用stub_prelude, bl stub_prelude; 該步驟中,bl stub_prelude用于調用stubj3relude()函數; 步驟306,結束。 該流程中,sp指棧指針寄存器。如圖4所示,是本發明的stubjrdude實現流程圖,并結合圖1、 2,由于 樁函數的序言部分被分為兩部分,而bootstrap實現流程已經做了一部分工作, 因此stubjrdude函數獲得了一個參數(r3),指向當前描述符數據結構地址, stub_prelude的流程具體包括步驟401,開始;步驟402,保存其他工作寄存器到棧楨,包括描述符數據結構指針; 步驟403,判斷一condition()是否為TRUE;若是,則調用樁函數,并結束;否則FALSE,恢復所有寄存器、sp,并跳轉到fallback,恢復恢復執行原功能函數B(),結束。prelude代碼是整個動態打樁的核心代碼部分,按照上述完成序言代碼的 編寫,就可以實現動態打樁的功能。如圖5所示,是本發明的單元測試裝置結構圖。該裝置50用于實現對軟 件系統10的單元測試,軟件系統10包括被測試模塊101;該裝置50包括生成編譯模塊501,用于根據被測試模塊101生成相應的測試模塊102, 并對被測試模塊101、測試模塊102進行編譯生成執行文件;動態打樁模塊502,用于運行執行文件,通過動態打樁完成被測試模塊101 與測試模塊102的掛接,執行測試;版本生成模塊503,用于修改編譯策略,去除對測試模塊101的編譯,生 成發布版本。本發明方法是一種采用動態打樁的軟件單元測試方法,適用于所有需要進 行單元測試的軟件系統,尤其適用于采用過程語言的軟件系統。采用本發明運行期動態打樁的單元測試方法,無需修改被測試代碼,保持 了被測試代碼的完整性,減小測試版本和發布版本的行為的差異性。當然,本發明還可有其他多種實施例,在不背離本發明精神及其實質的情 況下,熟悉本領域的技術人員當可根據本發明作出各種相應的改變和變形,但 這些相應的改變和變形都應屬于本發明所附的權利要求的保護范圍。
權利要求
1、一種單元測試方法,用于實現對軟件系統的單元測試,所述軟件系統包括被測試模塊,其特征在于,包括步驟一,根據所述被測試模塊設計生成相應的測試模塊,并對所述被測試模塊、所述測試模塊進行編譯生成一執行文件;步驟二,運行所述執行文件,通過動態打樁完成所述被測試模塊與所述測試模塊的掛接,執行測試;步驟三,修改編譯策略,去除對所述測試模塊的編譯,生成發布版本。
2、 根據權利要求1所述的單元測試方法,其特征在于,所述步驟二中, 由所述測試模塊的樁函數進行動態打樁完成所述被測試模塊與所述測試模塊 的掛接。
3、 根據權利要求2所述的單元測試方法,其特征在于,所述步驟二中, 所述樁函數根據一相應描述符的信息控制所述被測試模塊與所述測試模塊之 間的跳轉條件和相互聯系,所述描述符的信息包括跳轉前后序言代碼、控制 數據。
4、 根據權利要求3所述的單元測試方法,其特征在于,所述步驟二中,還包括在動態打樁時將所述跳轉前后序言代碼、所述控制數據保存至所述描述符的步驟。
5、 根據權利要求4所述的單元測試方法,其特征在于,所述步驟二中,還包括在進行動態打樁之前,由被測試函數調用原功能函數,并將原功能函 數的第一條指令替換為跳轉指令,跳轉至所述樁函數的序言中的步驟。
6、 根據權利要求5所述的單元測試方法,其特征在于,所述步驟二中, 由所述跳轉前后序言代碼完成所述原功能函數向所述樁函數的序言的跳轉。
7、 根據權利要求5或6所述的單元測試方法,其特征在于,所述步驟二中,還包括由所述樁函數的序言通過調用一條件函數判斷是執行所述樁函數還是返回至所述原功能函數繼續執行的步驟,若所述條件函數返回TRUE,則 執行所述樁函數,否則返回至所述原功能函數繼續執行。
8、 根據權利要求7所述的單元測試方法,其特征在于,所述步驟二中, 由所述條件函數根據由所述樁函數的路徑控制函數得到的路徑參數判斷是執行所述樁函數還是返回至所述原功能函數繼續執行。
9、 根據權利要求l、 2、 3、 4、 5、 6或8所述的單元測試方法,其特征在 于,所述步驟二中,還包括在所述執行測試完成后,刪除打樁的步驟。
10、 一種單元測試裝置,用于實現對軟件系統的單元測試,所述軟件系統包括被測試模塊,其特征在于,該裝置包括一生成編譯模塊,根據所述被測試模塊生成相應的測試模塊,并對所述被測試模塊、所述測試模塊進行編譯生成一執行文件;一動態打樁模塊,用于運行所述執行文件,通過動態打樁完成所述被測試 模塊與所述測試模塊的掛接,執行測試;及一版本生成模塊,用于修改編譯策略,去除對所述測試模塊的編譯,生成 發布版本。
全文摘要
本發明公開了一種單元測試方法及其裝置,用于實現對軟件系統的單元測試,所述軟件系統包括被測試模塊,其特征在于,該方法包括步驟一,根據所述被測試模塊設計生成相應的測試模塊,并對所述被測試模塊、所述測試模塊進行編譯生成一執行文件;步驟二,運行所述執行文件,通過動態打樁完成所述被測試模塊與所述測試模塊的掛接,執行測試;及步驟三,修改編譯策略,去除對所述測試模塊的編譯,生成發布版本。采用本發明保持待測試代碼的完整性,減小測試版本和發布版本的行為的差異性,方便測試代碼集中管理,使集成測試更容易,大大增強了單元測試理論的實踐可用性。
文檔編號G06F11/36GK101334753SQ200710117969
公開日2008年12月31日 申請日期2007年6月26日 優先權日2007年6月26日
發明者王云峰 申請人:中興通訊股份有限公司