gordonliweiID:gordonliwei
167310次访问,排名441好友0人,关注者10
gordonliwei的文章
原创 43 篇
翻译 0 篇
转载 0 篇
评论 266 篇
李维的公告
最近评论
quzhoushijie:gby杭州机票
杭州打折机票
杭州特价机票
WoW GoldWoW Gold
myshijieye:饰品加盟
浙江整形医院
浙江省人民医院
myshijieye:粉末涂料
购物篮
充电器
艺术漆
myshijieye:健康管理
飞凌
网络跳线
配线架
文章分类
    收藏
      相册
      作品集
      个人网站链接!
      博文视点读书热线(期书早知道)
      李维个人网站!
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 C++Builder 2007系列1-如何使用TDD For C/C++收藏

      新一篇: Delphi & VCL For Web技術研討會 | 旧一篇: 2007/06 Delphi&VCL For Web程式設計研討會

      C++Builder 2007系列1-如何使用TDD For C/C++

      現在不管開發人員是使用什麼程式語言,測試驅動開發(TDD)已經成為許多開發人員不二的選擇,在測試驅動開發框架JUnitJava開發界發行之後,xUnit系列很快的在各種不同的程式語言界中盛行,例如C#使用的NUnitDelphi使用的DUnit等。即使是如最近的新星Ruby也有著支援良好的測試驅動開發框架。但奇怪的是對於C/C++這樣老牌的程式語言,測試驅動開發框架的支援卻一直無法像JavaC#或是Delphi那樣的自然又能夠整合在IDE中讓C/C++的開發人員能夠很直覺又舒服的使用。

      但別誤會是C/C++沒有測試驅動開發框架,反之,目前有數個被使用的C/C++測試驅動開發框架,例如CppUnitBoost.TestUnit++CxxTest等。筆者本身在BCB2007沒有推出之前就是使用CxxTest,雖然我個人覺得CxxTestC/C++測試驅動開發框架最好用的,但是CxxTest仍然不是C/C++開發人員First-Class型態的C/C++測試驅動開發框架,它需要開發人員使用Perl或是Python轉換,又無法充分整合在筆者使用的IDE 中,因此不管是再熟練使用CxxTest,由於不是First-Class型態的C/C++測試驅動開發框架的原因,因此或多或少都拖慢了使用TDD For C/C++的開發速度。

      C++Builder 2007對於底層開發功能的強化之一就是它終於提供了TDD For C/C++的開發能力,C++Builder 2007藉由在DUnit之外提供了充分的C/C++ Wrapper類別和表頭檔而讓C/C++的開發人員能夠很自然的使用xUnit系列的標準測試驅動開發框架,而且又充分的整合在C++Builder 2007IDE(後文開始使用CUnit來代表C++Builder 2007提供的測試驅動開發框架),終於讓C/C++的開發人員擁有了First-Class型態的C/C++測試驅動開發框架,現在C++Builder的開發人員終於不必再屈就於不標準的C/C++測試驅動開發框架,也不必羨慕Java/C#/Delphi開發人員能夠擁有整合在IDE中的測試驅動開發框架,CUnit可以大幅增加C++Builder開發人員使用TDD方式開發軟體的速度。

      在下文中筆者將以一個簡單的範例來說明如何使用CUnit

      假設現在筆者需要撰寫一個C/C++類別來計算如下圖的汽車稅:
      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjkue4ukpLfG2PY9xwNf9I4s0wox9f8ZNcaylb-CWPCwyjE9bFi0QZF3

      從上圖中我們可以看到汽車稅種類非常的繁雜,使用TDD開發方式可以幫助我們快速的測試我們的程式碼是否正確。

      因此,首先我在C++Builder 2007中建立一個Package專案pkTDdDemo.bpl,並且在其中先建立一個TCarTax類別,其中TcarTax定義了一個Calculate方法,它最初的程式碼只提供上圖中『自用小客車』種類,1201CC1800CC級距中『燃料稅』的金額4800:

      int TCarTax::Calculate(const int iCC)

      {

      int iResult = 0;

      if (iCC >= 1201 && iCC <= 1800)

      iResult = 4800;

      return iResult;

      }

      一旦有了這個類別之後,我們可以立刻開始建立TDD專案,並且在TDD專案中建立測試案例(Test Case)來測試TCarTax::Calculate方法是否正確,如果一旦正確的話,那麼當我們繼續的加入更多的程式碼時,我們可以不斷的再執行測試案例以確保稍後加入的程式碼並沒有影響以前程式碼的正確性,也可以持續的增加新的測試案例以測試新加入的程式碼。
      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjl5_scY5zSYelXDWoi9k6ZcGE9tcw0Uo1KFCMX2VR8gjB-Jhd0-B9-_

      要建立TDD專案,讓我們先點選專案管理員中的專案群組節點,再點選滑鼠右鍵,選擇在專案群組中建立新的專案:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjmAt7XFHRAMNbaLro1bhrKLa-h6Vy3N-vYUUvOSkLGB42OSB2YIaAMG

      再選擇建立Unit Test|Test Project圖像建立TDD專案:
      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjn8KwkD_HtgDLVTQTyFlHXY_homIXbHqztwHtyymxlyw7TPg1UdBqZ_

      C++Builder 2007便會顯示如下的精靈詢問您有關TDD專案的細節,它會要求您建立TDD專案的名稱,例如在下面的精靈中我設定TDD專案的名稱為pkTDDDemoTestTCarTax。在Location中您可以選擇TDD專案儲存的目錄以及是否要把這個TDD專案加入目前的專案群組中:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjkJIQhNDikGui5g4XjK9VK4FlEWbDm7cHJadHbnr5mwJl7_OXs0gbJa

      點選Next之後,接著C++Builder 2007會詢問您使用的TDD測試界面為何,xUnit系列通常提供2種界面,GUIConsole模式,筆者習慣使用GUI模式,因此在下面的精靈中選擇GUI:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjkVb1YB10dZm7iWfwlFT2k7-wZCtpO9LfRGNi5ETYGDrIom8NAtbHCA

      最後點選Finish即可在產生如下的專案群組:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjntXyynGfCCI6n7bPvg5jsRjajcl4I9TVgj5SzN7SW6SEMCc2h_PPiF

      有了TDD專案之後,現在我們就可以繼續在其中建立測試案例了。在pkTDDDemoTestTCarTax專案中點選File|New|Other…功能表,在Unit Test中現在便會出現Test Case圖像,選擇它:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjmSDgDvr1IJP_FuZgEwKqRyNEmJGkUJubd86QjZS8r1RSSeZOU2H15S

      再於下一個對話盒中選擇我們要測試的C/C++類別TCarTax.h,此時精靈便會掃瞄整個表頭檔中定義在public的函式,這時它只找到Calculate,因此精靈便自動選擇要為這個函式產生測試案例。如果表頭檔中定義了許多的public函式,精靈會全部顯示出來並且讓開發人員選擇要為那些函式產生測試案例:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjnCSwnuLPydwBh5bXIZluUhRsDpLe_-Nh7UEq8qHYxUbpBWLPnqOwLE

      點選Finish之後,C++Builder便會產生如下的骨架測試類別和程式碼。由於本文目的不是教導TDD,因此不再解釋TDD基本的觀念:

      #include <vcl.h>

      #pragma hdrstop

      #include <TestFramework.hpp>

      class TTestTCarTax : public TTestCase

      {

      public:

      __fastcall virtual TTestTCarTax(AnsiString name) : TTestCase(name) {}

      virtual void __fastcall SetUp();

      virtual void __fastcall TearDown();

      __published:

      void __fastcall TestCalculate();

      };

      void __fastcall TTestTCarTax::SetUp()

      {

      }

      void __fastcall TTestTCarTax::TearDown()

      {

      }

      void __fastcall TTestTCarTax::TestCalculate()

      {

      // int Calculate(const int iCC)

      }

      static void registerTests()

      {

      _di_ITestSuite iSuite;

      TTestSuite* testSuite = new TTestSuite("Testing TCarTax.h");

      if (testSuite->GetInterface(iSuite)) {

      testSuite->AddTests(__classid(TTestTCarTax));

      Testframework::RegisterTest(iSuite);

      } else {

      delete testSuite;

      }

      }

      現在先include TCarTax的表頭檔定義在TTestTCarTax:

      #include "..\TCarTax.h"

      再於private中宣告一個物件變數:

      private:

      TCarTax *pTax;

      再於SetUpTearDown中分別建立和刪除物件變數:

      void __fastcall TTestTCarTax::SetUp()

      {

      pTax = new TCarTax();

      }

      void __fastcall TTestTCarTax::TearDown()

      {

      delete pTax;

      }

      最後就是在TTestTCarTax::TestCalculate()中撰寫測試程式碼了,例如首先我們可以撰寫如下的程式碼:

      void __fastcall TTestTCarTax::TestCalculate()

      {

      // int Calculate(const int iCC)

      CheckEquals(6120, pTax->Calculate(2000));

      }

      我們根據圖1測試TCarTax物件是否能夠正確的計算2000CC汽車的燃料稅是6120元。

      這時準備編譯pkTDDDemoTestTCarTax專案,先在專案管理員中加入TCarTax.cpp檔案以便可以連結到這個C/C++類別, 接著在IDE中執行它。我們就可以看到下面的TDD GUI程式出現中,點選上方綠色箭頭按鈕以執行測試TTestTCarTax::TestCalculate()的測試案例:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjmjJwbuJzciTY7vmCun2QgAvE93lYlT8Q_CC2z6UcVBSO5deOPdkPBR

      很快我們發現測試案例出錯了,它告訴我們TestCalculate期望回傳值是6120,但是實際的回傳值是0,所以這個測試案例不正確。為什麼? 原來我們還沒有撰寫2000CC汽車燃料稅的程式碼,目前只實作了1201~1800的汽車燃料稅,因此我們可以修改TestCalculate如下,:

      void __fastcall TTestTCarTax::TestCalculate()

      {

      // int Calculate(const int iCC)

      CheckEquals(4800, pTax->Calculate(1600));

      }

      再次執行測試:

      http://tkfiles.storage.msn.com/y1pPKnBvkPtOjndCRZ_L08w3mUN8qU6cXYaeKTOv4kCe3IdouyFv4QwB-dXWW7Hk36R

      測試案例就正確了。

      現在我們可以回到TCarTax類別的Calculate方法,再加入更多的實作程式碼,例如:

      int TCarTax::Calculate(const int iCC)

      {

      int iResult = 0;

      if (iCC >= 1201 && iCC <= 1800)

      iResult = 4800;

      else

      if (iCC >= 1801 && iCC <= 2400)

      iResult = 6212;

      return iResult;

      }

      然後在TTestTCarTax::TestCalculate()加入測試1801~2400CC的汽車燃料稅有沒有錯誤:

      void __fastcall TTestTCarTax::TestCalculate()

      {

      // int Calculate(const int iCC)

      CheckEquals(4800, pTax->Calculate(1600));

      CheckEquals(6210, pTax->Calculate(2000));

      }

      如此一直使用撰寫實作程式碼,撰寫測試案例周而復始下去,我們可以一直測試後加入的程式碼是否有影響到以前程式碼的正確性。

      好了,介紹到這裡我相信C++Builder的開發人員就瞭解如何使用C++Builder 2007中的TDD了。事實上如果讀者執行上照著上面步驟執行最後的TTestTCarTax::TestCalculate()測試案例是會產生失敗的,為什麼? 呵呵,因為我故意把實作程式碼寫錯了,留給讀者去改正好了,Have Fun!

       
       
       
       
       
       
       
       
       
       
       
       

      发表于 @ 2007年07月06日 12:01:00|评论(loading...)|编辑

      新一篇: Delphi & VCL For Web技術研討會 | 旧一篇: 2007/06 Delphi&VCL For Web程式設計研討會

      评论

      #iBuilder 发表于2007-07-06 16:00:40  IP: 59.39.176.*
      别忽悠人了,我不想说什么那个工具好的问题,我只想说我当年满腔热血学什么BCB,花了很多时间,最后才发现原来外面根本没人要,只好去DELPHI了!现在又只能学VC了,浪费了很多时间,青春阿,一两年的时间。当然某些知识是可以啦,但是毕竟DELPHI与VC还是有很不同的地方
      #ychpmj 发表于2007-07-06 16:40:23  IP: 61.144.248.*
      LS的,对你没有不代表别人没有,我所在的项目都是是用BCB开发的.
      #freebingo 发表于2007-07-06 16:50:35  IP: 221.220.89.*
      test
      #ccrun 发表于2007-07-06 18:08:02  IP: 221.204.224.*
      >>> 因為我故意把實作程式碼寫錯了,留給讀者去改正好了,Have Fun!

      哈哈。给了浮躁的读者没耐心看完,就照抄一遍去编译,结果出错,便又开始骂C++Builder了。
      #liudingming 发表于2007-07-06 18:09:23  IP: 219.143.46.*
      这哥们是谁啊
      #jjwwang 发表于2007-07-07 22:10:53  IP: 61.131.91.*
      别忽悠人了,我不想说什么那个工具好的问题,我只想说我当年满腔热血学什么BCB,花了很多时间,最后才发现原来外面根本没人要,只好去DELPHI了!现在又只能学VC了,浪费了很多时间,青春阿,一两年的时间。当然某些知识是可以啦,但是毕竟DELPHI与VC还是有很不同的地方

      //------------

      根风走的人,成不了真正的程序员。
      #huzhangyou 发表于2007-07-08 13:19:20  IP: 202.198.21.*
      [quote]
      别忽悠人了,我不想说什么那个工具好的问题,我只想说我当年满腔热血学什么BCB,花了很多时间,最后才发现原来外面根本没人要,只好去DELPHI了!现在又只能学VC了,浪费了很多时间,青春阿,一两年的时间。当然某些知识是可以啦,但是毕竟DELPHI与VC还是有很不同的地方

      [/quote]
      //------------

      开发的精髓不是语言,而是算法,模式,更不是IDE
      #justademo 发表于2007-07-08 13:34:46  IP: 218.18.91.*
      李老师:
      这个2007版本对Unicode的支持如何?我以前使用BCB6,后来升级到TurboC++Explorer,编写了一个比较大的工程,在中文和英语地区使用都没有问题,但是在Italy就经常Crash。程序本身(包括界面)都是英文的,没有做本地化处理。

      网上的朋友说VCL本身就不能在多语言环境中使用,是不是这样的?我无法确认。如果Crash是由于这个原因导致的,可能就不得不切换开发平台了。。。这个工作量太大了。。。真是让人焦虑。

      另外,2007版本会不会出TurboC++Explorer类似的版本?我现在非常担心TurboC++Explorer产品的延续性,如果这个也无法保证,可能也不得不切换开发平台。

      如果您能在百忙之中指点一下的话,那真是非常感谢。我的email地址是:justademo[at]msn.com

      谢谢
      #kenns2000 发表于2007-07-08 15:50:58  IP: 221.221.161.*
      Borland 始终都不愿为C++证明.
      始终都让C++成为Delphi的私生子.

      为什么Borland 不愿叙写C++的辉煌呢?
      #mrlong 发表于2007-07-09 09:06:41  IP: 220.184.166.*
      好的产品,我们只希望一个就行了,什么 C++build ,Delphi ,全心全力做好一个, 要做就做最好, 否则回家务农都比做第二强.

      下课了
      同学起立
      李老师好

      #treefox 发表于2007-08-03 09:38:30  IP: 220.173.11.*
      到现在为止,市面上或网络上c++builder 2007的教程几乎没有!!
      #czysoft 发表于2007-09-02 08:39:36  IP: 125.121.85.*
      致iBuilder老兄:
      BCB不可能没人要呀,只要你的EXE写得好,大可以自己做项目.何必屈身于他人?
      我当初就是从VB6->BCB6->vc++.net的
      每进一步,都有写好几个项目,全是自己一个人做的,虽然现在身体不太好了,但是技术上确实都有进步
      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © 李维