圖解MFC程式中使用Google單元測試工具GTest進行TDD開發(轉載)
Google釋出了很多開源的軟體,最近嘗試了一下Google的單元測試工具 GTest,發現很有特色。這裡 有 個不錯的入門教程。GTest有個特色很有意思就是測試方法不需要在標頭檔案定義,直接把實現寫在程式碼裡面就行了。寫好的測試用例(其實就是一個過程)自動 註冊到單元測試引擎,不需要手工註冊。但GTest在結果呈現方面比較弱,我所知道只有命令列輸出和XML輸出。CppUnit在這方面明顯強很多,有個 UI工具可用來選擇執行測試用例並展示結果。回到GTest,本著方便實用的原則,首選當然是命令列輸出了,XML輸出等專案大了再用吧。
前面提到的教程是基於SDK的,而在MFC GUI程式下面使用GTest還是有些區別的,好了,廢話少說,Action!
一,編譯GTest庫檔案
首先我們需要為MFC編譯GTest庫。VS下面開啟gtest工程檔案,開啟Configuration Manager,從Debug配置複製兩份新配置,分別起名為 Debug-MDd 和 Debug-MTd. 然後到專案管理器裡面重設所有專案的屬性,如圖分別設定相應的 Runtime Library。
編譯兩次Solution,生成gtest-1.3.0/msvc/Debug-MDd 和gtest-1.3.0/msvc/Debug-MTd
二,新建一個MFC專案
再次開啟Configuration Manager,從Debug配置複製一份新配置起名為Debug-Test, 然後設定專案配置
新增gtest-1.3.0/include 到專案的標頭檔案路徑裡,並設定一個預定義GTEST
三,到 xxxxApp::InitInstance() 新增程式碼,把測試啟動程式碼和MFC程式啟動程式碼分開 , 這樣以後選擇Debug就是普通模式下執行MFC程式,選擇Debug-Test就是執行測試用例。如圖:
- BOOL CPockerClientApp::InitInstance()
- {
- #ifdef GTEST
- CConsole cc;
- int argc = 0;
- TCHAR
* argv = _T(
""
);
- testing::InitGoogleTest(&argc, &argv);
- RUN_ALL_TESTS();
- HWND hwnd = GetConsoleWindow();
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
- AfxMessageBox(_T("about to exit!" ));
- return false ;
- #else
- // 如果一個執行 在 Windows XP 上的應用程式清單指定要
- // 使用 ComCtl32.dll 版本 6 或更高版本來啟用 視覺化方式,
- //則需 要 InitCommonControlsEx()。否則,將無法建立視窗。
- INITCOMMONCONTROLSEX InitCtrls;
- InitCtrls.dwSize = sizeof (InitCtrls);
- // 將它設定為包括所有要在應用程式中使用的
- // 公共控制元件類。
- InitCtrls.dwICC = ICC_WIN95_CLASSES;
- ......
- ......
- // 唯一的一個視窗已初始化,因此顯示它並對其進行更新
- m_pMainWnd->ShowWindow(SW_SHOW);
- m_pMainWnd->UpdateWindow();
- // 僅當具有後綴時才調 用 DragAcceptFiles
- // 在 SDI 應用程式中,這應 在 ProcessShellCommand 之後發生
- return TRUE;
- #endif //GTEST
- }
四,定義了一個CConsole 例項。
因為MFC GUI程式預設是沒有控制檯的,所以我們就看不到GTest的輸出。CConsole 就是用來建立一個控制檯物件並註冊為預設控制檯。程式碼如下:
- class CConsole
- {
- public :
- CConsole(void );
- virtual ~CConsole( void );
- private :
- };
- #include "StdAfx.h"
- #include "Console.h"
- #include <conio.h>
- #include <fcntl.h>
- #include <io.h>
- CConsole::CConsole(void )
- {
- AllocConsole();
- int hCrun;
- hCrun = _open_osfhandle((long )GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
- FILE * hFile = _fdopen(hCrun, "w" );
- // use default stream buffer
- setvbuf(hFile, NULL, _IONBF, 0);
- *stdout = *hFile;
- //test
- //_cprintf("test console by _cprintf/n", 0);
- //std::cout << "test console by std::out/n";
- }
- CConsole::~CConsole(void )
- {
- FreeConsole();
- }
測試執行完成以後,把Console視窗移到前臺,並通過MessageBox阻止程式退出,便於檢視控制檯的輸出。
五,輸出效果
怎麼樣,還不錯吧。順便說一下本文說的MFC程式指GUI MFC Dialog程式或Document View程式,不包括MFC控制檯程式 :P
六,補記
使用TDD開發方法意味著需要頻繁執行測試,建議大家在自己VS的介面上新增一個Start Without Debug的圖示,知道怎麼做吧,我就不多說了。
七,再補
這段時間試用下來發現GTest不能選擇部分測試用例單獨測試挺不爽的,特別是寫了好多測試用例,這些用例都依賴了具體實現的某個方法,但只有其中 幾個Fail了,這種情況下debug就太麻煩了,雖然可以用條件斷點之類的手段,畢竟沒有CPPUnit那樣按需選擇方便。從這個角度看,GTest還 不適合在測試用例比較多的專案中應用。
轉載自:http://blog.csdn.net/eyeblue/archive/2009/07/08/4332270.aspx