C++單元測試(6) - Game Programing Game 6 Ch1.7 首部曲

我一直覺得CppUnit的文件太少了,其實,也許是自己太弱了,所以才要這麼多的文件來教自己用這個厲害的工具。

試過了用VC6編譯cppunitlib用VS2010編譯cppunitlib,我還有另外去試了VS2005,結果也是超順利的編譯完成vs2005會遇到專案檔轉換出錯的問題,排除後就沒有特別要注意的地方了。(所以就沒有另外寫一篇介紹2005的了)
秘訣:更新該版本的VS到最新版
然後小心專案檔的設定。(參考上述兩篇)

還記得,我們在本系列第一篇中有提到到CppUnit的wiki有看到Refreance的段落吧?其實,有一個梗...不是啦!有一篇文章千千萬萬不可以錯過。那就是CppUnit1.13.2的作者在《Game Programming Gems 6》的Ch1.7寫了一篇CppUnit的教學。算是比CppUnit CookBook介紹得還要多一點點的教學文章。

所以,有興趣的朋友可以去下載來看看。

在這裡,我有依照這本書的1.7章做了練習,放在github上。
上面寫了一樣的code(還修改了一個小錯誤),也寫上了註解,很多的註解。
有興趣的朋友可以來這裡下載回去看看。

不過因為它是TDD,所以沒有待測物的class,只有完成了測試程式的部份。不過待測物很好寫啦!可以自己寫一寫....就可以跑囉!


《Game Programming Gems 6》的Ch1.7的內容,在這個部落格會分成三篇介紹。但是最重要的,還是要下載程式碼回去看唷!git就可以可以讓你一步一步的練習呢!

第一部曲

(34fe339~55c32ea)

建立治具類別

#ifndef FIXTURE_CLASS_H
#define FIXTURE_CLASS_H
#include "CppunitLib.h"
/*
在Cppunit中,我們要先建立治具類別。這可以從CppUnit::TestFixture衍生取得。
測試治具類別,就是一個容器類別,用來管理那些用於測試特定函數或類別的所有測試案例。
一個空的測試治具類別大致如下:
*/
class MathTest : public CppUnit::TestFixture
{
public:
    CPPUNIT_TEST_SUITE(MathTest);   //MathTest是TestFixture的衍生Class
    CPPUNIT_TEST_SUITE_END();
};
#endif

在治具類別上面放上待測物,再加上測試的功能內容

#ifndef FIXTURE_CLASS_H
#define FIXTURE_CLASS_H
#include "CppunitLib.h"
/*
在Cppunit中,我們要先建立治具類別。這可以從CppUnit::TestFixture衍生取得。
測試治具類別,就是一個容器類別,用來管理那些用於測試特定函數或類別的所有測試案例。
一個空的測試治具類別大致如下:
*/
class MathTest : public CppUnit::TestFixture
{
    /*
    在其中CPPUNIT_TEST_SUITE的巨集說明中,我們要說明這個測試治具類別執行的所有測試案例。
    例如,假設這個測試治具別要測試一個math類別,
    而你又需要一個特殊測試案例,來測試這個math類取的add函數。
    你可以像下面這段程式碼一樣,建立一個測試用的函數,來完成上述的實作。
    */
public:
    void TestAddFunction()
    {
        math my_math;
        CPPUNIT_ASSERT(my_math.Add(2, 2) == 4);
    }
    /*
    在這個測試案例中,我們呼叫math.add(2, 2),利用CppUnit提供的CPPUNIT_ASSRT巨集來驗證add呼叫的結果是否等於4。
    如果add函數沒有正確的返回結果4,CppUnit會在日誌文件中將這個錯誤記錄下來,並根據你所設置的報告輸出方式
    為你顯示這個錯誤訊息。

    在完成這個測試案例的實作之後,你要用CPPUNIT_TEST_SUITE巨集,將這個測試案例
    添加到測試治具類別中。
    */
public:
    CPPUNIT_TEST_SUITE(MathTest);   //MathTest是TestFixture的衍生Class
    CPPUNIT_TEST(TestAddFunction);  //TestAddFunction是待測的Function
    CPPUNIT_TEST_SUITE_END();
};
#endif

在測試主程式中寫下你要輸出的格式是什麼,並且執行

#include "CppunitLib.h"
#include "FixtureClass.h"
#include <iostream>

/*
既然你已經完成了撰寫測試案例的工作,並將它們添加到一個測試治具類別中進行管理,
現在你就需要建立一個測試執行模組(test harness),它會實際的執行這個測試治具類別(像工廠的機台),
並輸出最後執行結果。

我們可以這樣做:
1. 建立一個CppUnit::TextTestRunner物件,
2. 添加測試治具類別到CppUnit::TextTestRunner物件
3. 設定輸果的輸出格式
4. 執行CppUnit::TextTestRunner物件。

以這個例子來說,你可以將輸出結果重新定到一個xml文件中。
這個xml文件使用了一個樣式表來顯示輸出結果,更方便於瀏覽。
*/

int main()
{
 //第一步,就是建立測試的執行物件,一個CppUnit::TextTestRunner物件
 CppUnit::TextTestRunner runner;
 
 //接下來,建立output stream,指向我們保存輸出結果的xml檔。
 std::ofstream ofs("tests.xml");

 //要建立這個xml檔的handle(是一個CppUnit::XmlOutputter物件)
 //設定它的樣式表
 //設定runner的執行結果由hanle處理
 CppUnit::XmlOutputter *xml =
  new CppUnit::XmlOutputter(&runner.result(), ofs);
 xml->setStyleSheet("report.xsl");
 runner.setOutputter(xml);

 //最後,將所有你要執行的測試治具別(MathTest)加到這個runner物件
 runner.addTest(MathTest::suite());
 runner.run();

 std::cout << "end unti test" << std::endl;
 getchar();

 return 0;
}

沒有留言:

張貼留言

(什麼是留言欄訊息?)