裝上Vs2012 Rc,其中一個原因,是C++的原生單元測試,與以前.net下完全一致。這是很開心的事情,下面簡單的測試一下。
假設我們要使用Stl完成一項相對較通用的工作:為某個struct的vector,創建一個迭代器,用來返回struct的某個成員。這樣做的意義是什么呢?假設我們要對該結構的vector,基於其某個字段排序,只需要為sort算法提供這種類型的迭代器就行了。這樣算法就真正無需考慮容器“是什么”的問題。
當然,可以寫一個比較函數來使用sort,但若是自己寫的更復雜的算法呢?我們直接將struct數組,偽造成某個字段的數組,這樣豈非是最省事的方法?
那么我們先創建一個本機單元測試項目。
先寫測試代碼,意思很簡單,需要為某個vector創建迭代器器,檢查其返回值是否正確,檢查是否到了vector的最后位置:
TEST_METHOD(Iterator_Test) { vector<Quote> q; Quote quote={1.00,2.00}; q.push_back(quote); quote.open=2.00; q.push_back(quote); myit i(q.begin()); Assert::AreEqual((double)1.00, (double)(*i),0.0001, L"message", LINE_INFO()); ++i; Assert::AreEqual((double) 2.00, (double)(*i),0.0001, L"message", LINE_INFO()); ++i; Assert::AreEqual<vector<Quote>::iterator>(q.end(),i,L"message", LINE_INFO());
那么實現這項功能的方法也容易,代碼如下:
struct Quote { float open,close; }; class myit : public std::vector<Quote>::iterator { public: inline myit(std::vector<Quote>::iterator const &c):std::vector<Quote>::iterator(c) {} float operator*() { const Quote &p = std::vector<Quote>::iterator::operator*(); return p.open; } typedef float value_type; typedef float *pointer; typedef float &reference; };
注意,這里沒有做任何抽象,僅僅是簡單的實現一個針對vector<Quote>的迭代器,希望提供其作為算法的參數。若我們有興趣的話,可以簡單的抽象一下,針對任何容器,快速提供一個迭代器,返回其某個成員。類似Iterator<vector<Quote>,float,匿名函數返回某個成員> iter;當然,在抽象的過程中,現有的單元測試仍是有效的。這也是敏捷開發中很常見的次序:先寫測試表達意圖,再以最簡易的方法通過測試,必要的時候才考慮抽象。
我們打開測試試圖:列出已有的測試,選擇希望運行的,執行。單元測試在Ide內很好的集成工作,同時與Tfs德生成服務也能正常協同,類似Google Test之類的,從此可以好生休息了。