亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        測試驅(qū)動開發(fā)框架CxxTest原理分析

        2011-07-04 07:46:54艾智杰
        科技傳播 2011年20期
        關(guān)鍵詞:定義方法

        艾智杰

        同濟(jì)大學(xué)電子信息與工程學(xué)院計算機(jī)應(yīng)用技術(shù)系,上海 201804

        1 測試驅(qū)動開發(fā)簡介

        測試驅(qū)動開發(fā)(TDD)是一種基于循環(huán)開發(fā)的軟件開發(fā)過程。遵循TDD的編程人員,在正式進(jìn)行開發(fā)之前,通常先要確定在本階段需要實(shí)現(xiàn)的改進(jìn)或者新功能,然后通過編寫一系列的測試代碼來檢驗這些改進(jìn)和功能。一般情況下,這些測試代碼都會運(yùn)行失敗。接下去的任務(wù)便是編寫能夠使得這些測試通過的代碼,并且在完全通過測試后,重構(gòu)代碼,以達(dá)到生產(chǎn)標(biāo)準(zhǔn)。這個過程將會一直循環(huán)下去,直到所有的改進(jìn)或者功能完成。下圖展示了這一過程。

        圖1 基于TDD的開發(fā)循環(huán)

        2 CxxTest簡介

        CxxTest是專門為C++語言所開發(fā)的TDD框架。它具有不需要RTTI,可以承載外部庫,處理異常等優(yōu)點(diǎn)。作為一種輕量級框架,CxxTest將所有的代碼都僅包含在一個頭文件(tdd.h)中。也就是說,CxxTest框架僅需要一個現(xiàn)代C++編譯器就可以運(yùn)行測試程序,甚至在必要時,可以通過它捕獲異常和使用GUI展示。

        CxxTest作為一種輕量級的測試驅(qū)動開發(fā)框架,其優(yōu)點(diǎn)在于使用簡單。我們通常使用已有的控制臺測試啟動程序來調(diào)用我們自己編寫的測試用DLL。之后,該測試程序就會對此DLL的各個注冊方法進(jìn)行測試,并且最終輸出結(jié)果。

        3 CxxTest原理分析

        3.1 測試過程

        整個測試的過程大致可以分成兩個部分,第一部分是測試類的選取,而第二部分則是具體的對我們所定義的方法的測試。圖1表示的是在測試類級別上的選擇,而圖2則是圖1中帶有“*”標(biāo)記步驟的具體拓展,表現(xiàn)了CxxTest測試驅(qū)動開發(fā)框架如何逐個調(diào)用測試類中的各個測試方法。為了讓示意圖盡可能簡介,這里沒有顯示出異常處理。筆者將會另辟一節(jié)敘述。

        圖2 類的選取過程

        圖3 方法的測試過程

        3.2 類和方法的注冊

        測試類和方法的包裝注冊是整個測試開始前的準(zhǔn)備工作。這一步的注冊將會告訴CxxTest框架,有哪些類、其中的哪些方法需要進(jìn)行測試。

        整個注冊過程的第一階段是在編譯階段通過CxxTest框架自定義的宏將所有的類對象定義為全局變量。然后當(dāng)系統(tǒng)載入我們編寫的帶有測試類和方法的DLL時,首先會對全局變量進(jìn)行初始化,將所有這些經(jīng)過特殊處理的測試類對象加入到隊列中,以供后續(xù)使用。

        測試類的包裝注冊是通過TESTCLASS(CSomeClass)宏實(shí)現(xiàn)的。該宏最關(guān)鍵的代碼如下所示:

        該宏首先定義了函數(shù)CSomeClass _TddNamespaceResolv er::GetNameSpace() (未在上面的代碼中展示該函數(shù)細(xì)節(jié)),用于獲取CSomeClass的帶有命名空間的全稱,隨后,通過將TDD::ClassRegistrar< CSomeClass >類的匿名對象地址加入到全局智能指針中予以保留。

        這里起到關(guān)鍵作用的是TDD::ClassRegistrar類。在這里,我們只是使用了其構(gòu)造函數(shù)。由于該類繼承自TDD::ClassRegistrarBase類,所以在執(zhí)行自身的構(gòu)造函數(shù)之前,將會首先執(zhí)行TDD::ClassRegistrarBase類的構(gòu)造函數(shù),而查看代碼可知,該構(gòu)造函數(shù)的核心是調(diào)用了TDD::ClassRegistrarBase::AddCla ss()方法,該方法便是初始化測試類隊列,并且將各個測試類添加至隊列尾的真正執(zhí)行者。

        最后,必須指出的是,我們真正添加進(jìn)全局隊列的并不是CSomeClass類對象,而是經(jīng)過包裝的TDD::ClassRegistrar類對象,這個對象將會在其內(nèi)部產(chǎn)生CSomeClass對象(通過TDD::ClassRegistrar< CSomeClass >::GetInstance()方法),并且適時地調(diào)用CSomeClass的相關(guān)方法,同時也通過其構(gòu)造函數(shù)存儲了CSomeClass類的包含了命名空間的類全名。

        第二階段則是對測試類方法的注冊。這項功能是通過TESTMETHOD(MethodName)宏實(shí)現(xiàn)的。其核心代碼如下(略去次要部分)。

        這里著重解釋真正做測試類注冊工作的__m_ MethodName _variable,該變量在類對象的初始化過程中、類的構(gòu)造函數(shù)被觸發(fā)前先被初始化。

        仔細(xì)觀察該變量,他屬于TDD::MethodRegistrar型,其中T2(即源碼中的&MethodRegistrar_ MethodName _Wrapper)作為非類型模板參數(shù)被傳遞,框架將會通過這個方法來間接調(diào)用我們自定義函數(shù)的。關(guān)于MethodRegistrar類的與此有關(guān)的關(guān)鍵代碼如下,

        可見,其構(gòu)造函數(shù)僅僅是將測試方法加入隊列,而當(dāng)調(diào)用MethodRegistrar::RunTest()時,便會真正開始進(jìn)行測試。

        3.3 對方法進(jìn)行測試

        在初始化之后,程序便進(jìn)入了入口點(diǎn)函數(shù)TDD::UnitTestBase::RunTests()。該函數(shù)其實(shí)異常簡單,只是從隊列中找到測試類,然后再對每一測試類找到需要測試的方法,調(diào)用多態(tài)方法MethodRegistrar:: RunClassTests ()進(jìn)行測試,然后尋找下一個測試類,循環(huán)如此過程。

        MethodRegistrar:: RunClassTests ()的主要經(jīng)過正如“測試過程”一節(jié)中的圖2所示,具體對應(yīng)的函數(shù)也可以通過描述簡單匹配,這里就不再贅述了。至于如何由此函數(shù)調(diào)用方法測試的執(zhí)行者M(jìn)ethodRegistrar::RunTest(),再由此函數(shù)調(diào)用TESTMETHOD()宏所定義的包裝函數(shù),最后再回到我們自己的函數(shù)的過程,筆者將會在下一節(jié)展示。

        3.4 異常處理

        CxxTest的設(shè)計初衷就是為程序員提供測試框架,以檢查可能的錯誤。為了一方面檢查錯誤,另一方面在檢查到錯誤之后讓程序繼續(xù)執(zhí)行以運(yùn)行更多測試來檢查其他可能的錯誤,CxxTest的設(shè)計者對經(jīng)典的C++異常機(jī)制進(jìn)行了包裝。

        CxxTest使用了“模板方法”設(shè)計模式,將所有的異常機(jī)制都封裝在TryCatch類中,該類的模板方法便是TryCatch::Execute(),在基類中,設(shè)計者將其設(shè)計為純虛函數(shù),以后每當(dāng)需要進(jìn)行測試時,都會重新定義一個類(比如說用于做方法測試的TryCatchTest類),該類繼承自TryCatch類,并且重新實(shí)現(xiàn)Execute()函數(shù)。最終在測試時,框架則會調(diào)用

        TryCatch:: TryCatchAndReport()函數(shù),該函數(shù)的代碼如下所示(略去次要代碼)。

        那么CxxTest又是如何重定義Execute()函數(shù)呢?其實(shí),做法很簡單,他只是簡單地將Execute()函數(shù)定義為對MethodRegistrar::RunTest()的調(diào)用,該函數(shù)內(nèi)部又調(diào)用了在方法注冊時使用的那個測試方法的包裝函數(shù),然后由該包裝函數(shù)直接調(diào)用我們所定義的測試函數(shù)(就是在TESTMETHOD()宏后面的代碼)。

        再深一步,根據(jù)前面的分析,框架設(shè)計者認(rèn)為,應(yīng)該在Execute()函數(shù)中可能會拋出異常,而該函數(shù)實(shí)際上最終調(diào)用的是我們自己所定義的代碼,那我們自己的代碼一定需要定義異常嘛?其實(shí)不然,我們完全可以利用CxxTest框架所提供的驗證宏。這里我們僅針對最為常用的TDD_VERIFY(expression)宏進(jìn)行展開分析,其他類似。該宏的關(guān)鍵如下所示:

        其實(shí)他就是先判斷expression的真假,然后直接調(diào)用TDD::Verifier::Verify()函數(shù),此函數(shù)的功能非常簡單,就是判斷__tdd_b是否為假,如果為假,則拋出異常。關(guān)鍵代碼如下:

        4 結(jié)論

        CxxTest作為一款輕量級的TDD框架,在設(shè)計的時候充分利用了C++的各種特性,使得其運(yùn)作機(jī)制看似復(fù)雜卻條例清晰。本文理出了整個CxxTest框架的運(yùn)行主線,并且對其中較為重要的部分做出了詳細(xì)的解釋。

        [1]Robert C.Martin著.敏捷軟件開發(fā):原則,模式與實(shí)踐[M].鄧輝,等譯.清華大學(xué)出版社,2003,9.

        [2]Test-driven development.http://en.wikipedia.org/wiki/Test-driven_development.14 January 2010.

        [3]李瑛,彭軍.測試驅(qū)動開發(fā)在系統(tǒng)中的設(shè)計實(shí)現(xiàn)及效能分析[J].計算機(jī)與數(shù)字工程,2007,35(1).

        猜你喜歡
        定義方法
        永遠(yuǎn)不要用“起點(diǎn)”定義自己
        海峽姐妹(2020年9期)2021-01-04 01:35:44
        定義“風(fēng)格”
        學(xué)習(xí)方法
        可能是方法不對
        用對方法才能瘦
        Coco薇(2016年2期)2016-03-22 02:42:52
        成功的定義
        山東青年(2016年1期)2016-02-28 14:25:25
        四大方法 教你不再“坐以待病”!
        Coco薇(2015年1期)2015-08-13 02:47:34
        賺錢方法
        捕魚
        修辭學(xué)的重大定義
        97久久精品亚洲中文字幕无码| 区一区二区三免费观看视频| 青青草成人在线免费视频| 亚瑟国产精品久久| 亚洲AV电影天堂男人的天堂| 亚洲av综合色区在线观看| 久久99国产综合精品女同| 无码人妻aⅴ一区二区三区| 少妇人妻偷人精品一区二区| 国产成人精品免费视频大全| 日韩有码中文字幕在线视频 | 国产av无码专区亚洲av果冻传媒| 欧美另类高清zo欧美| 国产成人九九精品二区三区 | 人妻aⅴ中文字幕| 99国产精品视频无码免费| 国产成人夜色在线视频观看| 亚洲男人天堂一区二区| 久久久无码人妻精品一区| 久久精品一品道久久精品9| 一区二区三区四区免费国产视频| 成人免费播放视频777777| 久久综合久久鬼色| 久久久久国产精品片区无码| 国产日产韩国级片网站| 成年女人a级毛片免费观看| 中文字幕无码精品亚洲资源网久久| 99热高清亚洲无码| 人妻少妇精品视频一区二区三区l| 国产精品网站在线观看免费传媒 | 初女破初的视频| 国产精品玖玖玖在线资源| 人妻被公上司喝醉在线中文字幕 | 日日澡夜夜澡人人高潮| 精品无吗国产一区二区三区av| 国产区一区二区三区性色| 日日拍夜夜嗷嗷叫国产| 亚洲国产欧美在线成人| 久久精品av一区二区免费| 26uuu在线亚洲欧美| 久久久久国产一区二区三区|