`
csstome
  • 浏览: 1522217 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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!

分享到:
评论

相关推荐

    VC&C++builder TDD

    **VC&C++ Builder TDD(测试驱动开发)** 测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,它强调在编写实际代码之前先编写测试用例。这种方法鼓励开发者采用“红-绿-重构”循环,即首先编写...

    龙尚4G模块U8300模块驱动

    U8300无线模块是一款适用于FDD-LTE/TDD-LTE/TD-SCDMA/EDGE/GPRS/GSM多种网络制式的无线终端产品,U8300模块支持多种频段: Tri-Band TDD-LTE:Band38/39/40; Single-Band FDD-LTE :Band7; Tri-Band TD-SCDMA:...

    ibm-cloud-garage-tdd:https://github.comibm-cloud-academyibm-cloud-garage-tdd及其解决方案

    方便地,这意味着它在一个包中包含了TDD所需的所有内容(测试运行程序,断言,匹配器,间谍,存根和模拟) 玩笑的文档可以在这里找到: : 用npm install --save-dev jest 修改您的package.json文件,替换为: ...

    Modern C++ Programming with Test-Driven Development(Pragmatic,2013)

    Modern C++ Programming With Test-Driven Development, the only comprehensive treatment on TDD in C++ provides you with everything you need to know about TDD, and the challenges and benefits of ...

    Test Driven: Practical TDD and Acceptance TDD for Java Developers (PDF英文版)

    《Test Driven: Practical TDD and Acceptance TDD for Java Developers》是一本专注于Java开发者进行测试驱动开发(TDD)和验收测试驱动开发(Acceptance TDD)的专业书籍。这本书以PDF英文版的形式提供,旨在帮助...

    网络优化-LTE-FDD/TDD中级高级面试题目

    【网络优化-LTE-FDD/TDD中级高级面试题目】中的知识点涵盖了LTE网络的基本结构、信道配置、CSFB(电路交换 fallback)流程以及VoLTE(Voice over LTE)信令流程,这些都是LTE网络优化中非常重要的内容。以下是这些...

    中国移动通信频段划分.doc

    中国移动通信频段划分 中国移动 GSM900 上行/下行:890-909/935-954 EGSM900 上行/下行:885-890/930-935(中国铁通GSM-R:885-889/930-934) GSM1800M 上行/下行:1710-1725/1805-1820 3G TDD 1880-1900MHz和2010-...

    Laravel开发-laravel-tdd-docs

    **Laravel 开发 - 使用 TDD 进行高效构建** 在 Laravel 框架中,Test-Driven Development(TDD,测试驱动开发)是一种强大的软件开发方法论,它强调先编写测试,然后编写满足这些测试的代码。这种实践有助于确保...

    borgdash:开发联盟阵列乐趣!

    / ------------------------ / / ----| BorgDash TDD |---- / / ------------------------ / =) 不是那么有趣 数组乐趣/ -----[First Array Spec]----- / // 描述: // 获取数组的第一个元素或前 n 个元素。...

    tasks:任务教程

    辅导参考: -1- http://salayhin.wordpress.com/2012/10/19/test-driven-development-tdd-with-rails-3-and-rspec-part-1-2- ...rspec-part-2-3- ...

    软件工程思想--c c++编程指南--林锐

    《软件工程思想--C/C++编程指南--林锐》是一本深入探讨软件工程与C/C++编程实践的著作。作者林锐,以其丰富的经验和深入的理解,为读者提供了宝贵的编程指导和软件开发理念。 1. **软件工程思想**: - **需求分析*...

    angular-tdd-exemplar:TDD角度样例项目

    角TDD示例 介绍 此Angular TDD是考虑运行测试的Angular App构建的示例。 您可以克隆此存储库并将其用作您的应用程序的基础,或使用它来了解... --/scripts/ // location of our app logic --/index.html

    UMTS-TDD手册

    ### UMTS-TDD 手册知识点解析 #### 核心知识点概述 本文档主要针对的是**NS2网络仿真软件**中的**UMTS-TDD**(Universal Mobile Telecommunications System - Time Division Duplex)仿真方法进行了深入细致的介绍...

    A7600C-C1SE_硬件设计手册_V1.00.pdf

    A7600C-C1SE是一款支持多频段LTE-TDD/LTEFDD/GSM/GPRS/EDGE LTE CAT1模块。它可以支持最高 10Mbps下载速率和5Mbps上传速率。 A7600C-C1SE具有强大的扩展能力,包括UART, I2C, GPIO等丰富的接口。该模块为客户的...

    TDD-CDMA_for_Wireless_Communications

    ### TDD-CDMA在无线通信中的应用 #### 一、引言 TDD-CDMA(时分双工-码分多址)是无线通信技术中的一个重要分支,它结合了时分双工(TDD)与码分多址(CDMA)两种技术的特点,为移动通信系统提供了高效的数据传输解决...

    C-C++项目的测试驱动开发(TDD):从单元测试到集成测试.md

    在C/C++项目中应用测试驱动开发(TDD)的方法,从单元测试到集成测试,详尽介绍了测试的基础、框架选择、实际应用及最佳实践。文章首先阐述了TDD的核心理念及其优势,包括提升代码质量、减少错误和改进设计等。接着...

    API Design for C++的示例代码

    在C++编程中,API(应用程序接口)设计是构建可重用、可扩展且易于使用的软件组件的关键。API设计的好坏直接影响到代码的可维护性、性能和用户体验。本示例代码集着重展示了如何优雅地设计C++ API,遵循最佳实践和...

Global site tag (gtag.js) - Google Analytics