Redian新闻
>
现代 C++ 测试工具链(是时候抛弃 gtest/google bench 了)

现代 C++ 测试工具链(是时候抛弃 gtest/google bench 了)

公众号新闻

推荐关注↓

源:www.purecpp.org

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基本用法

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

TEST_CASE("vectors can be sized and resized") {
    std::vector<int> v(5);

    REQUIRE(v.size() == 5);
    REQUIRE(v.capacity() >= 5);

    SUBCASE("adding to the vector increases it's size") {
        v.push_back(1);

        CHECK(v.size() == 6);
        CHECK(v.capacity() >= 6);
    }
    SUBCASE("reserving increases just the capacity") {
        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宏类似,这两个宏也是平时做单测时用得最多的两个宏了。除此之外,还有更丰富的宏。比如:

<LEVEL> is one of 3 possible: REQUIRE/CHECK/WARN.

<LEVEL>_EQ(left, right) - same as <LEVEL>(left == right)
<LEVEL>_NE(left, right) - same as <LEVEL>(left != right)
<LEVEL>_GT(left, right) - same as <LEVEL>(left > right)
<LEVEL>_LT(left, right) - same as <LEVEL>(left < right)
<LEVEL>_GE(left, right) - same as <LEVEL>(left >= right)
<LEVEL>_LE(left, right) - same as <LEVEL>(left <= right)
<LEVEL>_UNARY(expr) - same as <LEVEL>(expr)
<LEVEL>_UNARY_FALSE(expr) - same as <LEVEL>_FALSE(expr)

判断异常的宏

CHECK_THROWS_AS(func(), const std::exception&);
CHECK_THROWS_AS(func(), std::exception); // same as above

CHECK_THROWS_WITH(func(), "invalid operation!");

CHECK_THROWS_WITH_AS(func(), "invalid operation!", std::runtime_error);

<LEVEL>_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库,用起来也很方便:

struct SomeInterface {
    virtual int foo(int) = 0;
    virtual int bar(string) = 0;
};

Mock<SomeInterface> mock;

When(Method(mock,foo)).Return(0);

SomeInterface &i = mock.get();

// Production code
i.foo(1);

// Verify method mock.foo was invoked.
Verify(Method(mock,foo));

// Verify method mock.foo was invoked with specific arguments.
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的库,使用起来也很简单,包含头文件即可。

#define ANKERL_NANOBENCH_IMPLEMENT
#include <nanobench.h>

int main() {
    double d = 1.0;
    ankerl::nanobench::Bench().run("some double ops", [&] {
        d += 1.0 / d;
        if (d > 5.0) {
            d -= 5.0;
        }
        ankerl::nanobench::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 | `some double ops`

总结

用现代C++测试工具链:doctest+FakeIt+nanobench, 可以完美地替代gtest/gmock和google bench,没有任何依赖,无需安装,直接包含头文件就可以用,非常容易集成和使用,是时候抛弃google test和google bench了!

- EOF -
推荐阅读  点击标题可跳转

1、为什么永远不会有语言取代 C / C++ ?

2、漫谈 C++:良好的编程习惯与编程要点

3、【Modern C++】深入理解移动语义


↓推荐关注↓

「CPP开发者」在 Github 维护着 9000+ star 的C/C++开发资源。日常分享 C语言 和 C++ 开发相关技术文章,每篇文章都经过精心筛选,一篇文章讲透一个知识点,让读者读有所获~


点赞和在看就是最大的支持❤️

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
3年坎坷,一战成名!摆脱「假精致」,你将会是Google想要的人China Strengthens Cyber Violence Policing After Teacher’s Death一年亏损100亿!从亚马逊Alexa到GoogleX,硅谷巨头「登月计划」纷纷被砍王羲之草书《如兄子书帖》Google Play推出用户评价“缓冲”机制,以打击评论轰炸行为离大谱!SF奶爸情急拍下孩子裸体照片,2天后,他竟被Google举报!全网通缉!Google、微软工程师花几十万把腿弄断,这件事在硅谷越来越流行Google旁边也能喝到Happy Lemon了? Kirkland这家新店真的是湖边赏秋必备!不是说好不懂就去问谷歌?google:问题太蠢,拒绝回答。有意思!Google二十年热搜词出炉!澳洲人最好奇的事是这些!惊呆!Google上澳洲人搜的最多的关键词公布!最爱买二手内裤?经济学专业可投!Google开放科技类Internship【新冠时代】蒙尘的日记(3)Google Analytics 4 面世,电商分析攻略大揭秘Chinese Drugmaker Launches Epilepsy Medicine After Approval​加国官宣!全国涨薪,科技行业涨幅最大,Amazon、Google疯抢留学生海投神器 | Google、Meta等1200+职位等待投递!让我来百度一下,为什么Google崩了2022庭院:菜篮子(07/29-08/09晨)Google:10个Intern,9个Return!【新冠时代】蒙尘的日记(4)Google Glass 发布 10 年后,AR 眼镜要成为下一个 iPhone 依然为时尚早裸辞Google码工,全职转型地产,这几年我经历了什么?Google 怒怼苹果,不用 iPhone 就会被排挤?China Golden Rooster & Hundred Flowers Film Festival wraps up谷歌“彻底放飞”俄罗斯!允许俄Google play应用接入三方支付因使用率过低 Google Translate不再向中国区域提供翻译服务历史新低!Google Chromecast 流媒体播放器 29.98元!bāo huā shēng?bō huā shēng?迟到的毕业典礼Google、Netflix、Amazon突放大量工作岗位!大波的上岸机会来了?A Top Archaeology Institute Struggles to Hire Archaeologists英国秋招 | Google 2023 Internship岗即将关闭投递通道!倒计时9天!Apple Car 最早 2026 年上市/Google 折叠屏即将面世/马斯克脑机公司涉嫌虐待动物被查Google解冻摇人,Meta再放校招岗!快速秋招上岸通道开启?
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。