gtest的问题
gtest需要安装有时候带来很多不方便,比如需要经常切换gcc和clang的时候就比较麻烦,安装的gtest可能在另一个编译器下编译不过, 编写跨平台程序的时候需要多次安装gtest,非常不便。另外一个问题是网络原因,下载安装gtest或者git上拉gtest都可能因为网络原因失败。
现代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),当然也比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更酷更实用的一个特性是SUBCASE, 允许在当前case下增加更多的子case去测试一些special一些的东西,非常实用,这也是相比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< right) _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的异常断言更强大,可以同时比较异常类型和异常信息。
也许有人会说gtest除了这些基本的测试断言之外还有gmock呀,doctest没有gmock这样的mock库。是的,doctest确实没有mock库,但是doctest很容易和其它现代C++的mock库结合起来使用,比如FakeIt。
现代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库也是需要编译/安装的,有没有什么现代C++的benchmark库来替代google 的benchmark库呢?当然有,比如nanobench。
现代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); }); }
测试结果:
|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`
总结
用现代C++测试工具链:doctest+FakeIt+nanobench, 可以完美地替代gtest/gmock和google bench,没有任何依赖,无需安装,直接包含头文件就可以用,非常容易集成和使用,是时候抛弃google test和google bench了!
-
文件
+关注
关注
1文章
587浏览量
25917 -
C++
+关注
关注
22文章
2122浏览量
76709 -
编译器
+关注
关注
1文章
1669浏览量
51081
原文标题:现代 C++ 测试工具链(是时候抛弃 gtest/google bench 了)
文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
现代C++项目的最佳实践
用Visual C++做数据库开发
Linux下C/C++编译器gcc使用指南
doctest基本用法
C++学习笔记之c++的基本认识
C++学习笔记之顺序容器
C和C++编写环境下LabVIEW如何调用动态库?

现代C++ unit test库之doctest基本用法
评论