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

  1. C++單元測試(6) - Game Programing Game 6 Ch1.7 首部曲
    1. 第一部曲
      1. 建立治具類別
      2. 在治具類別上面放上待測物,再加上測試的功能內容
      3. 在測試主程式中寫下你要輸出的格式是什麼,並且執行

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

原文連結: https://darkblack01.blogspot.com/2014/10/cgame-programing-game-6-ch17.html
移植時的最後更新日期: 2015-12-26T14:17:37.593+08:00

我一直覺得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;
}