背景
TDD測試驅動開發是當前流行的開發方法及模式。遵循TDD的方法對開發程序庫(Library)特別有用,因為Library就是為第三方提供一定功能接口的實現,使用TDD的方法可以預先為定義的接口提供測試案例,保證實現代碼能通過測試,保證Library能如實的實現預定義的功能。我之前開發的Mobile Sensors API的庫,由于沒有編寫單元測試,得到了一些不好的反饋,現在把單元測試引進到該庫里面,提高該庫的質量。關于該Mobile Sensors API庫的開發可以參考 Windows Mobile下的重力感應器(Gravitational Sensor)開發。關于wince和Windows mobile下的native C++的測試可以參考 Wince和Windows Mobile下native C++的單元測試。關于CF平臺下的測試可以參考 .NET Compact Framework下的單元測試。 使用TDD的一個實例可以參考 Windows Mobile下猜數字游戲的TDD實現。
簡介
本文講述Windows Mobile下使用CppUnitLite對native c++進行unit test的時候,如何把測試結果輸出到文件的開發。使之支持Mobile Sensors API庫。
實現
由于原版的CppUnitLite只是支持把測試結果打印到標準輸出里面,但是Windows Mobile默認是沒有console輸出的,所以要對CppUnitLite進行修改使之支持把結果輸入到文件里。
修改定義
#include <stdio.h>
class Failure;
class TestResult
{
public:
TestResult (char* _fileName = 0);
virtual void testsStarted ();
virtual void addFailure (const Failure& failure);
virtual void testsEnded ();
private:
int failureCount;
char* fileName;
FILE* fileStream;
};
這個功能的實現需要修改TestResult類,首先增加fileName變量保持輸出文件路徑和名字,增加fileStream保存文件流的句柄。然后修改TestResult的構造函數,原構造函數是沒有輸入參數的,如TestResult ();修改為增加文件路徑和名字輸入參數。 TestResult (char* _fileName = 0);為了保持原先client代碼的源碼級兼容,這個參數有默認值為0(空,NULL)。這里說的client源碼級的兼容是指client的代碼不需要進行任何的修改就可以支持修改后的新庫,這符合軟件設計過程的Open-Close Principle。但是這修改不支持運行時兼容,client需要重新編譯(因為頭文件修改了)和鏈接(因為CppUnitLite靜態庫更新了)。
更新實現
TestResult::TestResult (char* _fileName)
: failureCount (0),
fileName(_fileName)
{
}
void TestResult::testsStarted ()
{
if(fileName != NULL)
{
fileStream = fopen(fileName, "w");
}
else
{
fileStream = stdout;
}
}
修改啟動測試函數,當文件名不為空的時候,生成輸出文件流(stream)。如果為空時,使用標準輸出流。
void TestResult::addFailure (const Failure& failure)
{
fprintf (fileStream, "%s%s%s%s%ld%s%s\n",
"Failure: \"",
failure.message.asCharString (),
"\" " ,
"line ",
failure.lineNumber,
" in ",
failure.fileName.asCharString ());
failureCount++;
}
void TestResult::testsEnded ()
{
if (failureCount > 0)
fprintf (fileStream, "There were %ld failures\n", failureCount);
else
fprintf (fileStream, "There were no test failures\n");
if(fileName != NULL && fileStream != NULL)
{
fflush(fileStream);
fclose(fileStream);
fileStream = NULL;
}
}
清理資源,在Wince和Windows Mobile下,有時候需要顯式(explicit)的調用fflush,否則有些輸出不能同步到文件中去。
Client的修改
//Unit Test
TestResult tr("TestResult.txt");
TestRegistry::runAllTests(tr);
修改client的代碼很簡單,只需要在生成TestResult 的對象是傳遞文件名就可以了,如果不傳遞絕對路徑,文件會生成到根目錄下。
關于Mobile Sensors API項目
這個項目還是在起步階段,當前實現了samsung的重力感應器,我把項目host到 Mobile Sensors API - Native unified APIs for Windows Mobile Sensors 了,我會持續改進,把各種sensors的實現到這個項目中。
由于我手頭上沒有HTC的機器,如果誰有興趣可以加入到項目中幫我測試HTC設備,由于加入了Unit Test,測試變得很簡單,只需要執行程序,參考測試輸出文件就可以了,不需要調試。當然這個測試過程是一個不斷迭代的過程,只是Unit Test把子過程簡單化了。
源代碼:http://mobilesensor.codeplex.com/SourceControl/ListDownloadableCommits.aspx
環境:VS2008 + WM 6 professional SDK + Samsung Windows Mobile SDK