0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

現(xiàn)代C++ unit test庫之doctest基本用法

Linux愛好者 ? 來源:Linux愛好者 ? 作者:Linux愛好者 ? 2022-10-09 16:38 ? 次閱讀

gtest的問題

gtest需要安裝有時候帶來很多不方便,比如需要經常切換gcc和clang的時候就比較麻煩,安裝的gtest可能在另一個編譯器下編譯不過, 編寫跨平臺程序的時候需要多次安裝gtest,非常不便。另外一個問題是網絡原因,下載安裝gtest或者git上拉gtest都可能因為網絡原因失敗。

現(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),當然也比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_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很容易和其它現(xiàn)代C++的mock庫結合起來使用,比如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庫呢?當然有,比如nanobench。

現(xiàn)代C++ benchmark庫

nanobench(https://github.com/martinus/nanobench)也是C++11寫的header only的庫,使用起來也很簡單,包含頭文件即可。

#defineANKERL_NANOBENCH_IMPLEMENT
#include

intmain(){
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`

總結

用現(xiàn)代C++測試工具鏈:doctest+FakeIt+nanobench, 可以完美地替代gtest/gmock和google bench,沒有任何依賴,無需安裝,直接包含頭文件就可以用,非常容易集成和使用,是時候拋棄google test和google bench了!

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 文件
    +關注

    關注

    1

    文章

    566

    瀏覽量

    24744
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73651
  • 編譯器
    +關注

    關注

    1

    文章

    1634

    瀏覽量

    49132

原文標題:現(xiàn)代 C++ 測試工具鏈(是時候拋棄 gtest/google bench 了)

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    現(xiàn)代C++項目的最佳實踐

    本系列是開源書C++ Best Practises[1]的中文版,全書從工具、代碼風格、安全性、可維護性、可移植性、多線程、性能、正確性等角度全面介紹了現(xiàn)代C++項目的最佳實踐。本文是該系列的第三篇。
    發(fā)表于 09-29 11:32 ?1149次閱讀

    C++STL算法(二)

    C++STL算法(二)
    的頭像 發(fā)表于 07-18 14:49 ?1052次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>STL算法(二)

    c++STL算法(三)

    c++STL算法(三)
    的頭像 發(fā)表于 07-18 15:00 ?1294次閱讀
    <b class='flag-5'>c++</b><b class='flag-5'>之</b>STL算法(三)

    C++文件操作

    C++文件操作
    的頭像 發(fā)表于 07-21 10:52 ?1115次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>文件操作

    用Visual C++做數據開發(fā)

    實驗 用Visual C++做數據開發(fā) 一、實驗目的1、了解數據的訪問方式,掌握ADO 方式訪問數據2、用 Visual C++制作
    發(fā)表于 05-10 10:54 ?2442次閱讀

    c++標準手冊

    C++的標準手冊,新手學習的好資料,同時也是開發(fā)人員的必備手冊。里面涵蓋了標準C++的所有的庫函數。
    發(fā)表于 11-03 14:05 ?43次下載

    The C++ Standard Library

    C++標準英文版。 C++強大的功能來源于其豐富的類及庫函數資源。
    發(fā)表于 05-13 14:41 ?0次下載

    Linux下C/C++編譯器gcc使用指南

    1.gcc包含的c/c++編譯器 gcc,cc與c++,g++ gcc和cc是一樣的,c++和g++是一樣的。一般c程序就用gcc編譯,
    發(fā)表于 11-02 10:59 ?0次下載

    C語言和C++的特點與用法詳細說明

    本文檔的主要內容詳細介紹的是C語言和C++的特點與用法詳細說明。
    的頭像 發(fā)表于 12-26 10:58 ?4421次閱讀

    doctest基本用法

    現(xiàn)代C++測試工具鏈:doctest+FakeIt+nanobench, 可以完美地替代gtest/gmock和google bench,沒有任何依賴,無需安裝,直接包含頭文件就可以用,非常容易集成和使用,是時候拋棄googl
    發(fā)表于 08-05 10:43 ?1299次閱讀

    C++設計新思維-泛型編程與設計應用

    C++設計新思維-泛型編程與設計應用
    發(fā)表于 11-16 15:59 ?3次下載

    C++學習筆記c++的基本認識

    自這篇文章我們即將開始C++的奇幻之旅,其內容主要是讀C++ Primer的總結和筆記,有興趣可以找原版書看看,對于學習C++還是有很大幫助的。這篇文章將從一個經典的程序開始介紹C++
    的頭像 發(fā)表于 03-17 13:57 ?739次閱讀

    C++學習筆記順序容器

    C++中的順序容器是一種用于存儲和管理元素序列的數據結構。它們提供了一組有序的元素,并支持在序列的任意位置插入和刪除元素。C++標準中提供了多種順序容器,包括vector、deque、list、forward_list和arr
    的頭像 發(fā)表于 05-11 17:05 ?597次閱讀

    CC++編寫環(huán)境下LabVIEW如何調用動態(tài)?

    C語言編寫的動態(tài)鏈接相比,不同的地方在于extern int “C” __declspec(dllexport) add(int x,int y) 這一導出語句,在C代碼中沒有”
    發(fā)表于 06-11 09:15 ?7777次閱讀
    <b class='flag-5'>C</b>和<b class='flag-5'>C++</b>編寫環(huán)境下LabVIEW如何調用動態(tài)<b class='flag-5'>庫</b>?

    C++之父新作帶你勾勒現(xiàn)代C++地圖

    為了幫助大家解決這些痛點問題,讓大家領略現(xiàn)代C++美,掌握其中的精髓,更好地使用C++C++之父Bjarne Stroustrup坐不住
    的頭像 發(fā)表于 10-30 16:35 ?855次閱讀
    <b class='flag-5'>C++</b>之父新作帶你勾勒<b class='flag-5'>現(xiàn)代</b><b class='flag-5'>C++</b>地圖