GoogleTest从入门到入门,小白都能看懂的gtest详细教程

这篇具有很好参考价值的文章主要介绍了GoogleTest从入门到入门,小白都能看懂的gtest详细教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单元测试

项目管理和技术管理中做单元测试,衡量一个软件是否正常的标准,良好的单元测试以及足够多的覆盖率,至少保证关键功能,关键业务的覆盖率接近100%。

gtest是谷歌公司发布的一个跨平台(Linux、Mac OS、Windows等)的C++单元测试框架,它提供了丰富的断言、致命和非致命判断、参数化、死亡测试等等。

  • 两种断言:

    • ASSERT_*:当断言失败时,产生致命错误、并终止当前函数。
    • EXPECT_*:当断言失败时,产生非致命错误,并且不会终止当前函数。
    • 通常都会用EXPECT_*,因为能在一次测试中测试出更多的失败情况。
    • 如果要在出现失败测试时立即终止程序,则要选择ASSERT_*
    • ==注意:==因为ASSERT_*会在失败时立即终止函数,那么就可能跳过后面程序中进行清理工作的代码,可能会产生内存泄露。

测试stack

main函数在gtest_main.cc中,可以把这个main函数复制到你的代码里面,你将拥有它的控制权。

GTEST_API_ int main(int argc, char **argv) {
    std::cout << "Running main() from gtest_main.cc\n";
    
    testing::InitGoogleTest(&argc, argv);//解析命令行中的GoogleTest参数,它允许用户通过多样的命令行参数来控制测试程序的行为(即定制命令行参数的行为)
    return RUN_ALL_TESTS();//将会搜索不同的Test Case和不同的源文件中所有已经存在测试案例,然后运行它们,所有Test都成功时返回1,否则返回0。
}
  • 非致命断言,即使宏判断失败,程序仍然会顺序执行后面的代码

    每一个测试实例都必须初初始化每一个对象

    ==TEST()宏==的第一个参数是Test Case的名称,第二个参数是隶属于第一个Test Case参数的Test的名称。GoogleTest根据Test Case对测试结果进行分组,所以一些相关的Test应该放在同一个Test Case中。

    #include "gtest/gtest.h"
    #include "MyStack.h"
    
    //测试实例1
    TEST(testStack, simpletest) {
        MyStack st;
        st.push(4);
        EXPECT_EQ(4, st.pop());//使用Google Test宏进行测试(非致命断言)
    }
    
    //测试实例2
    TEST(testStack, testAll) {
        MyStack st;
        st.push(9);
        st.push(28);
        
        int val = st.pop();
        EXPECT_EQ(28, val);//28等于val则测试通过(非致命断言)
        EXPECT_NE(0,val);//0不等于val则测试通过(非致命断言)
        EXPECT_GT(29, val);//29大于val则测试通过(非致命断言)
        EXPECT_GE(29, val);//29大于等于val则测试通过(非致命断言)
        EXPECT_TRUE(val == 28) << "val is not equal to 28";//val == 28结果为false,输出后面日志(非致命断言)
    }
    
  • 致命断言,如果断言失败,当前函数剩下来的代码将会被跳过

    TEST(testStack, testAll) {
        MyStack st;
        st.push(9);
        st.push(28);
        
        int val = st.pop();
        ASSERT_EQ(28, val);//28等于val则测试通过(致命断言)
        ASSERT_NE(0,val);//0不等于val则测试通过(致命断言)
        ASSERT_GT(29, val);//29大于val则测试通过(致命断言)
        ASSERT_TRUE(val == 28) << "val is not equal to 28";//val == 28结果为false,输出后面日志(致命断言)
    }
    
  • 字符串断言

    TEST(testStack, testAll) {
        MyStack st;
        st.push(9);
        st.push(28);
        
        int val = st.pop();
    	
        EXPECT_EQ("9", st.toString().c_str());//字符串断言
    }
    
  • 浮点数断言

    TEST(testStack, testAll) {
        MyStack st;
        st.push(9);
        st.push(28);
        
        int val = st.pop();
    	
        EXPECT_FLOAT_EQ(7.0, ((float)val)/4);
        EXPECT_DOUBLE_EQ(7.0, ((double)val)/4);
    }
    
  • 测试装置(Test Fixtures)

    假如我们有非常多的测试实例,不想重复初始化

    TEST_F()宏,我们想让多个Test使用同一套数据配置时,就需要用到测试装置,创建测试装置的具体方法如下:

    • 派生一个继承 ::testing::Test 的类,并将该类中的一些内容声明为 protected 类型,以便在子类中进行访问;
    • 根据实际情况,编写默认的构造函数或SetUp()函数,来为每个 test 准备所需内容;
    • 根据实际情况,编写默认的析构函数或TearDown()函数,来释放SetUp()中分配的资源;
    • 根据实际情况,定义 test 共享的子程序。

    不同用例之间,数据实际都是独占的,不会相互影响。

    TEST_F()宏的第一个参数(即Test Case的名称)必须是测试装置类的类名。

    对于TEST_F()定义的每个Test,Google Test将会在运行时创建一个新的测试装置对象,并立即通过SetUp()对其进行初始化,然后运行这个Test,之后通过TearDown()进行数据清理,最后删除测试装置对象。==同一个Test Case中不同的test具有不同的测试装置对象,并且Google Test每次创建新的测试装置前都会先删除之前的测试装置。==多个Test不会重用相同的测试装置,某个Test对测试装置进行修改对其他Test无影响。

    #include "gtest/gtest.h"
    #include "MyStack.h"
    
    //MyStackTest继承于testing命名空间下的Test类
    class MyStackTest : public testing :: Test {
    protected:
    	//总是在测试用例开始时被调用
        virtual void SetUp() {
    		st.push(34);
    		st.push(28);
    		st.push(56);
    	}
        
        //总是在测试用例结束后被调用
        virtual void TearDown() {
            
        }
        
        //构造函数,也可以做一部分SetUp函数的工作
        MyStackTest() {
            std::cout << "MyStackTest is constructed." << std::endl;
            st.push(22);
        }
        //析构函数,也可以做一部分TearDown函数的工作
        ~MyStackTest() {
            std::cout << "Destructed MyStackTest." << std::endl;
        }
        
        MyStack st;
    };
    
    //如果使用了测试装置,就必须使用TEST_F(测试装置类, 自定义名称)
    TEST_F(MyStackTest, testPop) {
        //在这里会自动构造一个MyStack的实例,并调用SetUp函数
        int val = st.pop();
        EXPECT_EQ(56, val);
        //在这里会调用TearDown函数
    }
    
    //testPop2和testPop来自同一个测试装置,但是来自不同的测试装置实例,两个实例是相互独立的个体
    TEST_F(MyStackTest, testPop2) {
        //在这里会自动构造一个MyStack的实例,并调用SetUp函数
        int val = st.pop();
        EXPECT_EQ(56, val);
        //在这里会调用TearDown函数
    }
    
  • 全局事件

    要实现全局事件,必须写一个类,继承testing::Environment类,==定义一个该全局环境的一个对象并将该对象添加到全局环境测试中去。==实现里面的SetUpTearDown成员函数。SetUp在所有案例执行前执行,TearDown在所有案例执行后执行。

    #include "gtest/gtest.h"
    
    class GlobalTest : public testing::Environment {
    public:
        void SetUp() {
            std::cout << "SetUp" << std::endl;
        }
        void TearDown() {
            std::cout << "TearDown" << std::endl;
        }
    };
    
    TEST(abs_test, test_1) {
        EXPECT_EQ(std::abs(-1), 1);
    }
    
    TEST(abs_test, test_2) {
        EXPECT_EQ(std::abs(0), 0);
    }
    
    int main(int argc, char **argv) {
        std::cout << "Running main() from gtest_main.cc\n";
        
        testing::InitGoogleTest(&argc, argv);
        testing::Environment* env = new GlobalTest();
        testing::AddGlobalTestEnvironment(env);
        return RUN_ALL_TESTS();//将会搜索所有已经存在测试案例,然后运行他们
    }
    
  • 死亡测试文章来源地址https://www.toymoban.com/news/detail-464710.html

    ASSERT_DEATH(参数1, 参数2);//程序挂了并且错误信息和参数2匹配,此时认为测试通过。如果参数2为空字符串,则只需要看程序挂没挂即可。
    ASSERT_EXIT(参数1, 参数2);//语句停止并且错误信息和被提前给的信息匹配。
    

到了这里,关于GoogleTest从入门到入门,小白都能看懂的gtest详细教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 小白也能看懂的ChatGPT知识介绍

    ChatGPT 是一款由 OpenAI 开发的人工智能技术驱动的语言模型应用。以下是 ChatGPT 的主要特点和功能: 自然语言处理:ChatGPT 可以识别和理解自然语言,包括英语、法语、德语、西班牙语等多种语言。它可以回答各种问题、提供各种建议,并与人类进行自然的对话。 语言模型:

    2024年02月06日
    浏览(34)
  • 小白也能看懂的零信任SDP介绍

    SDP全称是Software Defined Perimeter,即软件定义边界,是由国际云安全联盟CSA于2013年提出的基于零信任(Zero Trust)理念的新一代网络安全技术架构。 一个经典访问关系普遍都可汇总为这样的访问模型:【终端】-【网络】-【业务系统】。访问最初是由终端产生请求,通过网络发送给

    2024年02月08日
    浏览(35)
  • 【概念】区块链中账本是什么?通用区块链平台账本概念介绍,一个谁都能看懂的账本概念

    目录 前言 举个例子 账本在不同链中担任什么角色 联盟链 公有链 私有链 随着区块链的发展,目前国内也掀起了一阵区块链的热潮,无论是金融、信任、交易、溯源等领域都是非常受欢迎,慢慢的我们也将成为第一个吃螃蟹的人,本篇文章主要是与大家一起聊聊什么是区块链

    2023年04月10日
    浏览(28)
  • 智能车上位机系统,pyqt下的socket通信,python实现服务器+客户端,文本+视频不定长字节传输,超详细,小白都能看懂

    目录 前言: 准备工作: 初级服务器端编写: 中级服务器端编写+客户端收数据函数实现: 数据包格式v1.0 客户端收数据函数V1.0 客户端分析1.0     本地测试:成功!      两台主机测试1.0:失败,视频解析失败,直接花屏了! 问题分析: 问题解决: 数据包格式V2.0 客户端接

    2024年04月17日
    浏览(38)
  • [免费专栏] Android安全之Android Xposed插件开发,小白都能看得懂的教程

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬请移步知识星球 感谢大家一直以来对我CSDN博客的关注和支持,但

    2024年02月09日
    浏览(26)
  • 等保2.0丨5分钟速览:小白也能看懂的等保2.0介绍

    等级保护2.0自2019年12月1日正式实施起,到现在已经有两个多月的时间,但是仍然有刚刚进入等保领域的“萌新”反馈,需要小编再做一个简单的介绍,那么今天的干货内容,我们就来一起了解什么是等保2.0,最新实施的2.0又和之前的1.0有哪些区别,新增了什么? 等保2.0的概

    2024年02月15日
    浏览(41)
  • 小周带你读论文-2之“草履虫都能看懂的Transformer老活儿新整“Attention is all you need(2)

    书接前文:小周带你读论文-2之\\\"草履虫都能看懂的Transformer老活儿新整\\\"Attention is all you need(1) (qq.com)       上文书说到为什么我们要用casual-decoder架构,把Transformer的左边给省略了,于是得到下图这样的架构       上图是GPT-1的模型结构,那么casual-decoder和原始Transformer除了没

    2024年01月21日
    浏览(36)
  • WPS AI最全申请与使用手册;AIGC制作游戏音乐;便宜快捷使用完整版SD;人人都能看懂的ChatGPT原理课 | ShowMeAI日报

    👀 日报周刊合集 | 🎡 生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 作者在这篇文章中探讨了生成式AI在虚拟世界的应用,并绘制了 Market Map V3.0 (市场全景图),来展示 Experiences 、 Discovery、Creator Economy、Spatial Computing、Decentralization、Human Interface、Infrastructure 各部分

    2024年02月09日
    浏览(31)
  • 【vue-element-admin】github高质量vue项目解读,小白都能看懂(第三篇)

    日月几何,天地玄黄,今日奇观,书接上一回。 这次我们来讲 panel-group / 组件 因为本文是跟着项目来的,所以不从第一篇看起的小伙伴云里雾里,所以针对以上情况,我决定对于 vue-element-admin 项目出现的大部分技术栈以及知识点(比如:element-ui,echarts,vuex等等)进行讲解

    2024年02月02日
    浏览(43)
  • 基于蚁群算法的机器人路径规划matlab——代码注释超级详细,都能看懂

    本文对基本蚁群算法代码进行了详细的注释,每一步都简单易懂。程序在matlab中可直接运行,适合刚开始学习本算法的同学入门。 蚁群算法是由意大利学者Dorigo提出的一种仿生智能算法,最早运用在旅行商问题上。蚁群算法模仿蚂蚁觅食过程设计出的智能启发式算法,蚂蚁觅

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包