最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++?單元自動(dòng)化測(cè)試解決方案總結(jié)

 更新時(shí)間:2022年06月22日 09:21:48   作者:??vivo互聯(lián)網(wǎng)技術(shù)???  
這篇文章主要介紹了C/C++?單元自動(dòng)化測(cè)試解決方案總結(jié),通過(guò)利用GCC插件來(lái)實(shí)現(xiàn)提升C/C++開發(fā)者的單元效率工具解決方案,希望對(duì)大家在提升單元測(cè)試效率上有所啟發(fā)

前言

C/C++ 開發(fā)效率一直被業(yè)內(nèi)開發(fā)人員詬病,單元測(cè)試開發(fā)效率也是如此,以至于開發(fā)人員不愿花時(shí)間來(lái)寫單元測(cè)試。那么我們是不是可以通過(guò)改善編寫單元測(cè)試的效率來(lái)提升項(xiàng)目的測(cè)試用例覆蓋率?

本文主要介紹如何利用GCC插件來(lái)實(shí)現(xiàn)提升C/C++開發(fā)者的單元效率工具解決方案,希望對(duì)大家在提升單元測(cè)試效率上有所啟發(fā)。

一、動(dòng)機(jī)

上圖展示了C/C++單元測(cè)試的基本流程,在日常開發(fā)過(guò)程中寫單元測(cè)試是一項(xiàng)比較大工程量的事情,C/C++ 目前單元測(cè)試代碼都需要自己手動(dòng)寫,而且對(duì)于一些私有方法打樁就更加麻煩。

目前業(yè)內(nèi)無(wú)開源的自動(dòng)化測(cè)試框架或者工具,倒是有一些商業(yè)的自動(dòng)測(cè)試工具,下圖展示了我們自動(dòng)化測(cè)試工具及單元測(cè)試庫(kù):

即使開源界有g(shù)test等測(cè)試庫(kù)的支持,我們?nèi)匀恍枰帉懘罅康膯卧獪y(cè)試用例代碼。對(duì)于一些private、protected的類方法,編寫單元測(cè)試用例的效率就更低,需要手動(dòng)打樁(mock)。同時(shí)我們分析測(cè)試用例發(fā)現(xiàn),存在很多邊界的用例,它們基本上都是很固定或者有一定模式,比如int 最大最小值等。

如何改善編寫單元測(cè)試的效率,提升C/C++同學(xué)開發(fā)效率以及程序質(zhì)量?我們可以通過(guò)提取源文件中的函數(shù)、類等信息,然后生成對(duì)應(yīng)的單元測(cè)試用例。自動(dòng)生成用例時(shí)需要依賴函數(shù)的聲明、類的聲明等信息,那么我們應(yīng)該如何獲取這些信息呢?

例如:如下的函數(shù)定義:

void test(int arg) {}

我們希望能夠從上面的函數(shù)定義中得到函數(shù)的返回值類型、函數(shù)名稱、函數(shù)參數(shù)類型、函數(shù)作用域。通常我們可以通過(guò)以下幾種方式得到:

1.1 方法1:使用正則表達(dá)式

無(wú)奈C/C++ 格式比較復(fù)雜能夠雖然能夠使用多種組合來(lái)獲取對(duì)應(yīng)的函數(shù)聲明等信息:

void test(int arg){}
void test1(template<template<string>> arg,...){}
void test2(int(*func)(int ,float,...),template<template<string>> arg2){}

那么就需要寫一系列的正則表達(dá)式:

  • 提取函數(shù)名稱、參數(shù)名:[z-aA-Z_][0-9]+
  • 提取函數(shù)返回值:^[a-zA-Z_]

關(guān)鍵詞提取出來(lái)了,但是他有一個(gè)很大的問題:怎么判斷文件中書寫的代碼是符合C/C++語(yǔ)法描述呢?

1.2 方法2:使用flex/bison 分析c/c++源碼文件

這當(dāng)然是一種很好的方式,但是工作量巨大,相當(dāng)于實(shí)現(xiàn)一個(gè)具備詞法、語(yǔ)法分析器簡(jiǎn)易版本的編譯器,而且要適配不同的語(yǔ)法格式,雖然bison可以解決上述的如何判斷語(yǔ)法是否正確問題,但是仍然很復(fù)雜。

1.3 方法3:利用編譯已經(jīng)生成的AST 來(lái)生成代碼

通常我們了解到的GCC編譯的過(guò)程是以下四個(gè)階段:

源文件->預(yù)處理->編譯->匯編→鏈接

但實(shí)際上GCC為了支持更多的編程語(yǔ)言、不同的CPU架構(gòu)做了很多的優(yōu)化,如下圖所示:

上圖展示了GCC處理源碼及其他優(yōu)化過(guò)程,在前端部分生成的Generic 語(yǔ)言是gcc編譯過(guò)程中為源碼生成的一種與源碼語(yǔ)言無(wú)關(guān)的抽象語(yǔ)法表現(xiàn)形式(AST)。既然GCC編譯過(guò)程中生成了AST樹,那么我們可以通過(guò)GCC插件來(lái)提取GCC 前端生成的抽象語(yǔ)法樹關(guān)鍵信息比如函數(shù)返回值、函數(shù)名稱、參數(shù)類型等??傮w難度也很高,一方面業(yè)內(nèi)可參考資料很少,只能通過(guò)分析GCC的源碼來(lái)分析AST語(yǔ)法樹上的各個(gè)節(jié)點(diǎn)描述。

本文所描述的自動(dòng)化生成單元測(cè)試用例的解決方案(我們稱之為TU:Translate Unit,后文統(tǒng)稱為TU)就是基于方法3來(lái)實(shí)現(xiàn)的,下面我們先來(lái)看看我們的自動(dòng)化測(cè)試用例解決方案的效果展示。

二、效果展示

2.1 業(yè)務(wù)代碼零修改, 直接使用TU生成邊界用例

在該用例中我們不需要修改任何業(yè)務(wù)代碼就能夠?yàn)闃I(yè)務(wù)代碼生成邊界測(cè)試用例,而且函數(shù)參數(shù)可邊界值實(shí)現(xiàn)全排列,大大降低用例遺漏風(fēng)險(xiǎn)。大家可能發(fā)現(xiàn)這種沒有做任何修改生成的用例是沒有斷言的,雖然沒有斷言,它仍然能夠幫助發(fā)現(xiàn)單元是否會(huì)存在邊界值引起coredump。

那么如果想要給他加上斷言、mock函數(shù),是否沒有辦法呢?通過(guò)C++11 [[]] 新的屬性語(yǔ)法,只需要在方法聲明或者定義時(shí)添加下根據(jù)TU的格式添加斷言即可,對(duì)業(yè)務(wù)邏輯無(wú)侵入。

2.2 使用注解tu::case生成用戶自定義用例

很多情況下默認(rèn)生成的邊界測(cè)試用例還不能覆蓋到核心邏輯,所以我們也提供tu::case 來(lái)給用戶自定義自己的測(cè)試用例及斷言。比如有一個(gè)int foo (int x,long y) 方法,現(xiàn)在想新增一個(gè)測(cè)試用例返回值123,函數(shù)實(shí)參1,1000,那么只要在函數(shù)聲明前加入,以下代碼即可:

[[tu::case("NE","123","1","1000")]]

2.3 使用注解tu::mock 自動(dòng)生成mock方法

開發(fā)過(guò)程中我們也常需要對(duì)某個(gè)方法進(jìn)行mock(即對(duì)原有方法設(shè)置一個(gè)臨時(shí)代替方法并且調(diào)用方式保持一致),比如某個(gè)函數(shù)訪問Redis、DB這種情況下進(jìn)行單元測(cè)試往往需要對(duì)這些方法進(jìn)行mock,方便其他函數(shù)調(diào)用進(jìn)行單元測(cè)試,為了方便進(jìn)行單元測(cè)試我們往往會(huì)對(duì)其進(jìn)行mock,所以為了方便開發(fā)人員進(jìn)行快速的mock,所以我們提供了tu::mock 的注解幫助開發(fā)同學(xué)快速的定義注解,然后TU會(huì)自動(dòng)生成對(duì)應(yīng)的mock函數(shù)。例如:現(xiàn)在給foo_read 方法mock一個(gè)函數(shù),讓mock的函數(shù)返回10:

三、TU實(shí)現(xiàn)方案

3.1 AST 是什么?

GENERIC、GIMPLE和RTL三者構(gòu)成了gcc中間語(yǔ)言的全部,它們以GIMPLE為核心,由GENERIC承上,由RTL啟下,在源文件和目標(biāo)指令之間的鴻溝之上構(gòu)建了一個(gè)三層的過(guò)渡。

GCC在語(yǔ)法分析過(guò)程中,所有識(shí)別出來(lái)的語(yǔ)言部件都用一個(gè)叫TREE的變量保存著。這個(gè)TREE就是GCC語(yǔ)法樹(AST),這個(gè)過(guò)程叫做GENERIC。實(shí)際上它也是GCC的符號(hào)表,因?yàn)樽兞棵?、類型等等這些信息都由TREE關(guān)聯(lián)起來(lái)。

下面我們通過(guò)gcc編譯選項(xiàng)來(lái)看下gcc的ast表現(xiàn)形式:

3.2 AST(Abstract syntax tree)

GCC 可以通過(guò)添加編譯選項(xiàng)-fdump-tree-all 來(lái)生成ast 樹,ast樹文件內(nèi)容如下:

AST 各個(gè)類型描述可以參考:gcc.gnu.org/onlinedocs/…

雖然上圖中簡(jiǎn)單看下一下可以發(fā)現(xiàn),gcc這種表現(xiàn)形式節(jié)點(diǎn)與節(jié)點(diǎn)之間還存在依賴,比較難于理解,沒有clang生成的直觀更容易閱讀。雖然不利于閱讀,但是不影響通過(guò)編碼來(lái)提取AST信息。

3.3 方案

如上圖所示,我們通過(guò)使用不同的插件收集被測(cè)試源文件的AST信息、頭文件信息、函數(shù)注解(屬性),將這些重要信息保存起來(lái)。

GCC將用戶注冊(cè)插件事件保存到數(shù)組中:

然后在編譯構(gòu)建過(guò)程中到就會(huì)去查找對(duì)應(yīng)的事件有沒有設(shè)置回調(diào)方法如果設(shè)置則進(jìn)行調(diào)用,TU主要使用以下幾種插件:

  • PLUGIN_INCLUDE_FILE 用于獲取當(dāng)前文件的所包含的頭文件
  • PLUGIN_OVERRIDE_GATE 用戶獲取普通函數(shù)、類
  • PLUGIN_PRE_GENERICIZE 用于獲取模板函數(shù)的具現(xiàn)化
  • PLUGIN_ATTRIBUTES 用于實(shí)現(xiàn)自定義屬性或者注解(tu::case\tu::mock ....)

GCC 支持的所有插件類型如下圖所示:(摘自gcc 6.3.0 源碼)

四、TU 插件使用的簡(jiǎn)易程度對(duì)比

如果僅僅只是做邊界測(cè)試那么僅需要修改構(gòu)建的腳本比如cmake 添加對(duì)應(yīng)的插件參數(shù)即可。

五、使用TU的優(yōu)點(diǎn)

  • 接入簡(jiǎn)單、邊界單元測(cè)試可以做到業(yè)務(wù)代碼0修改
  • 函數(shù)參數(shù)可邊界值實(shí)現(xiàn)全排列,大大降低用例遺漏風(fēng)險(xiǎn)、減少大量重復(fù)性的工作
  • 快速生成用戶自定義用例、mock方法等

六、TU支持的功能

七、總結(jié)與展望

1、文章中對(duì)比了三種方法自動(dòng)生成測(cè)試用例的方法,下面對(duì)這幾種方法進(jìn)行對(duì)比:

2、文章中還主要介紹了TU的功能特點(diǎn)以及基于GCC-AST的實(shí)現(xiàn)自動(dòng)生成測(cè)試用例的解決方案。

TU解決方案目前在構(gòu)建時(shí)能夠自動(dòng)生成測(cè)試用例已經(jīng)極大降低了單元測(cè)試門檻提升單元測(cè)試覆蓋率,未來(lái)我們也希望能夠把TU與IDE相結(jié)合,探索更高效便捷的使用方式,通過(guò)更加便捷的方式生成指定方法的測(cè)試用例。比如通過(guò)在函數(shù)、方法上,通過(guò)快捷鍵生成當(dāng)前方法的測(cè)試用例等。

到此這篇關(guān)于C/C++ 單元自動(dòng)化測(cè)試解決方案總結(jié)的文章就介紹到這了,更多相關(guān) C++ 單元測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • win10+VS2017+Cuda10.0環(huán)境配置詳解

    win10+VS2017+Cuda10.0環(huán)境配置詳解

    這篇文章主要介紹了win10+VS2017+Cuda10.0環(huán)境配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • C++如何動(dòng)態(tài)的生成對(duì)象詳解

    C++如何動(dòng)態(tài)的生成對(duì)象詳解

    C++是不支持根據(jù)類名動(dòng)態(tài)地生成對(duì)象的,比如從一個(gè)文本文件中讀取類名然后構(gòu)造一個(gè)對(duì)象.主要原因是沒有豐富的動(dòng)態(tài)元信息,沒有單根類庫(kù)。那么下面這篇文章就來(lái)給大家介紹C++是如何動(dòng)態(tài)的生成對(duì)象,有需要的朋友們可以參考借鑒。
    2017-02-02
  • C語(yǔ)言中關(guān)于scanf函數(shù)的一些問題詳解

    C語(yǔ)言中關(guān)于scanf函數(shù)的一些問題詳解

    這篇文章主要為大家介紹了C語(yǔ)言中關(guān)于scanf函數(shù)的一些問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • C語(yǔ)言三子棋的實(shí)現(xiàn)思路到過(guò)程詳解

    C語(yǔ)言三子棋的實(shí)現(xiàn)思路到過(guò)程詳解

    所謂三子棋,就是三行三列的棋盤,玩家可以和電腦下棋,率先連成三個(gè)的獲勝。這篇文章主要為大家詳細(xì)介紹了如何通過(guò)C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,感興趣的小伙伴可以嘗試一下
    2023-02-02
  • C++類中的六大默認(rèn)成員函數(shù)詳解

    C++類中的六大默認(rèn)成員函數(shù)詳解

    這篇文章主要介紹了C++類中的六大默認(rèn)成員函數(shù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C++實(shí)現(xiàn)LeetCode(135.分糖果問題)

    C++實(shí)現(xiàn)LeetCode(135.分糖果問題)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(135.分糖果問題),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • VS2019安裝配置MFC(安裝vs2019時(shí)沒有安裝mfc)

    VS2019安裝配置MFC(安裝vs2019時(shí)沒有安裝mfc)

    這篇文章主要介紹了VS2019安裝配置MFC(安裝vs2019時(shí)沒有安裝mfc),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • C語(yǔ)言素?cái)?shù)(質(zhì)數(shù))判斷的3種方法舉例

    C語(yǔ)言素?cái)?shù)(質(zhì)數(shù))判斷的3種方法舉例

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言素?cái)?shù)(質(zhì)數(shù))判斷的3種方法,質(zhì)數(shù)是只能被1或者自身整除的自然數(shù)(不包括1),稱為質(zhì)數(shù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • 如何用C語(yǔ)言生成簡(jiǎn)單格式的xml

    如何用C語(yǔ)言生成簡(jiǎn)單格式的xml

    本篇文章是對(duì)使用C語(yǔ)言生成簡(jiǎn)單格式的xml的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語(yǔ)言數(shù)據(jù)的存儲(chǔ)專項(xiàng)分析

    C語(yǔ)言數(shù)據(jù)的存儲(chǔ)專項(xiàng)分析

    使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-07-07

最新評(píng)論

资阳市| 南华县| 遂川县| 青阳县| 凭祥市| 平遥县| 邹平县| 石河子市| 凭祥市| 惠水县| 黄大仙区| 崇阳县| 尚义县| 桦南县| 临江市| 潮安县| 九龙坡区| 蕉岭县| 衡东县| 防城港市| 岐山县| 始兴县| 桦南县| 青海省| 独山县| 黄冈市| 皮山县| 军事| 木兰县| 彰武县| 乡城县| 大冶市| 高碑店市| 家居| 孝义市| 桑日县| 嘉兴市| 随州市| 晋宁县| 明水县| 英山县|