gtest的問題
gtest需要安裝有時候帶來很多不方便,比如需要經(jīng)常切換gcc和clang的時候就比較麻煩,安裝的gtest可能在另一個編譯器下編譯不過, 編寫跨平臺程序的時候需要多次安裝gtest,非常不便。另外一個問題是網(wǎng)絡(luò)原因,下載安裝gtest或者git上拉gtest都可能因?yàn)榫W(wǎng)絡(luò)原因失敗。
現(xiàn)代C++ unit test庫
除了gtest之外,還有很多輕量級易用的單元測試庫,比如doctest和catch,相比gtest需要編譯/安裝,他們都是header only的,直接包含到工程里就可以做單元測試了,portable又沒有任何依賴,而且對編譯器版本要求也不高,只需要C++11就行了,用了之后只有一個字:爽!
這里推薦使用doctest(https://github.com/doctest/doctest),原因是它的性能比catch更好(https://github.com/doctest/doctest/blob/master/doc/markdown/benchmarks.md),當(dāng)然也比gtest好, 來看看doctest怎么用的吧。
doctest基本用法
#defineDOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include"doctest.h" TEST_CASE("vectorscanbesizedandresized"){ std::vectorv(5); REQUIRE(v.size()==5); REQUIRE(v.capacity()>=5); SUBCASE("addingtothevectorincreasesit'ssize"){ v.push_back(1); CHECK(v.size()==6); CHECK(v.capacity()>=6); } SUBCASE("reservingincreasesjustthecapacity"){ v.reserve(6); CHECK(v.size()==5); CHECK(v.capacity()>=6); } }
這里使用CHECK做斷言和gtest的EXPECT_xx是類似的,我覺得doctest更酷更實(shí)用的一個特性是SUBCASE, 允許在當(dāng)前case下增加更多的子case去測試一些special一些的東西,非常實(shí)用,這也是相比gtest更好的一個地方。
doctest提供了很多豐富的宏,完全可以滿足我們的測試需要。
doctest的斷言宏
CHECK宏是只檢查并不會終止測試,REQUIRE宏則會終止測試和gtest里面的ASSET_XX宏類似,這兩個宏也是平時做單測時用得最多的兩個宏了。除此之外,還有更豐富的宏。比如:
isoneof3possible:REQUIRE/CHECK/WARN. _EQ(left,right)-sameas (left==right) _NE(left,right)-sameas (left!=right) _GT(left,right)-sameas (left>right) _LT(left,right)-sameas (left_GE(left,right)-sameas (left>=right) _LE(left,right)-sameas (left<=?right) _UNARY(expr)-sameas (expr) _UNARY_FALSE(expr)-sameas _FALSE(expr)
判斷異常的宏
CHECK_THROWS_AS(func(),conststd::exception&); CHECK_THROWS_AS(func(),std::exception);//sameasabove CHECK_THROWS_WITH(func(),"invalidoperation!"); CHECK_THROWS_WITH_AS(func(),"invalidoperation!",std::runtime_error);_NOTHROW(expression)
doctest異常的宏非常有特色,比gtest的異常斷言更強(qiáng)大,可以同時比較異常類型和異常信息。
也許有人會說gtest除了這些基本的測試斷言之外還有g(shù)mock呀,doctest沒有g(shù)mock這樣的mock庫。是的,doctest確實(shí)沒有mock庫,但是doctest很容易和其它現(xiàn)代C++的mock庫結(jié)合起來使用,比如FakeIt。
現(xiàn)代C++ mock庫
FakeIt(https://github.com/eranpeer/FakeIt)是C++11寫的header only的mock庫,用起來也很方便:
structSomeInterface{ virtualintfoo(int)=0; virtualintbar(string)=0; }; Mockmock; When(Method(mock,foo)).Return(0); SomeInterface&i=mock.get(); //Productioncode i.foo(1); //Verifymethodmock.foowasinvoked. Verify(Method(mock,foo)); //Verifymethodmock.foowasinvokedwithspecificarguments. Verify(Method(mock,foo).Using(1));
用doctest+FakeIt兩個header only的庫就可以完美替代gtest了。那么還有一個就是benchmark了,google有一個benchmark庫也是需要編譯/安裝的,有沒有什么現(xiàn)代C++的benchmark庫來替代google 的benchmark庫呢?當(dāng)然有,比如nanobench。
現(xiàn)代C++ benchmark庫
nanobench(https://github.com/martinus/nanobench)也是C++11寫的header only的庫,使用起來也很簡單,包含頭文件即可。
#defineANKERL_NANOBENCH_IMPLEMENT #includeintmain(){ doubled=1.0; ankerl::Bench().run("somedoubleops",[&]{ d+=1.0/d; if(d>5.0){ d-=5.0; } ankerl::doNotOptimizeAway(d); }); }
測試結(jié)果:
|ns/op|op/s|err%|ins/op|cyc/op|IPC|bra/op|miss%|total|benchmark |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:---------- |7.52|132,948,239.79|1.1%|6.65|24.07|0.276|1.00|8.9%|0.00|`somedoubleops`
總結(jié)
用現(xiàn)代C++測試工具鏈:doctest+FakeIt+nanobench, 可以完美地替代gtest/gmock和google bench,沒有任何依賴,無需安裝,直接包含頭文件就可以用,非常容易集成和使用,是時候拋棄google test和google bench了!
-
文件
+關(guān)注
關(guān)注
1文章
561瀏覽量
24675 -
C++
+關(guān)注
關(guān)注
21文章
2102瀏覽量
73457 -
編譯器
+關(guān)注
關(guān)注
1文章
1617瀏覽量
49019
原文標(biāo)題:現(xiàn)代 C++ 測試工具鏈(是時候拋棄 gtest/google bench 了)
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論