gtest的介绍和使用

gtest的介绍和使用一、什仫是gtestgtest是一个跨平台的(Liunx、MacOSX、Windows、Cygwin、WindowsCEandSymbian)C++单元测试框架,由google公司发布。gtest是为在不同平台上为编写C++测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。了解了什仫是gtest之后下面让我们来学习gt…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、什仫是gtest
gtest是一个跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)C++单元测试框架,由google公司发布。gtest是为在不同平台上为编写C++测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。
了解了什仫是gtest之后下面让我们来学习gtest的一些使用规则吧!
一、gtest系列之TEST宏

TEST(test_case_name, test_name)
TEST_F(test_fixture,test_name)  //多个测试场景需要相同数据配置的情况,用TEST_F。TEST_F test fixture,测试夹具,测试套,承担了一个注册的功能。
  
  
  
  • 1
  • 2

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。后续文章还会提到TEST_P这个宏,在这里就先不介绍了。


二、gtest系列之断言
gtest中断言的宏可以分为两类:一类是ASSERT宏,另一类就是EXPECT宏了。
1、ASSERT_系列:如果当前点检测失败则退出当前函数
2、EXPECT_系列:如果当前点检测失败则继续往下执行
如果你对自动输出的错误信息不满意的话,也是可以通过operator<<能够在失败的时候打印日志,将一些自定义的信息输出。
ASSERT_系列:

bool值检查
1>、 ASSERT_TRUE(参数),期待结果是true
2>、ASSERT_FALSE(参数),期待结果是false
数值型数据检查
3>、ASSERT_EQ(参数1,参数2),传入的是需要比较的两个数  equal
4>、ASSERT_NE(参数1,参数2),not equal,不等于才返回true
5>、ASSERT_LT(参数1,参数2),less than,小于才返回true
6>、ASSERT_GT(参数1,参数2),greater than,大于才返回true
7>、ASSERT_LE(参数1,参数2),less equal,小于等于才返回true
8>、ASSERT_GE(参数1,参数2),greater equal,大于等于才返回true
字符串检查
9>、ASSERT_STREQ(expected_str, actual_str),两个C风格的字符串相等才正确返回
10>、ASSERT_STRNE(str1, str2),两个C风格的字符串不相等时才正确返回
11>、ASSERT_STRCASEEQ(expected_str, actual_str)
12>、ASSERT_STRCASENE(str1, str2)
13>、EXPECT_系列,也是具有类似的宏结构的
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

下面我们来做一个测试,实现一个求绝对值的函数,并在TEST宏里面使用ASSERT来进行测试不同类型的数据。

#include<iostream>
using namespace std; 
#include<gtest/gtest.h>

int Abs(int x)
{
     return x > 0 ? x : -x;
}

TEST(IsAbsTest,HandlerTrueReturn)
{
    ASSERT_TRUE(Abs(1) == 1) << "Abs(1)=1";  //ASSERT_TRUE期待结果是true,operator<<输出一些自定义的信息
    ASSERT_TRUE(Abs(-1) == 1) << "Abs(-1)=1";
    ASSERT_FALSE(Abs(-2) == -2);  //期待结果是false
    ASSERT_EQ(Abs(1),Abs(-1));
    ASSERT_NE(Abs(-1),0);
    ASSERT_LT(Abs(-1),2);
    ASSERT_GT(Abs(-1),0);
    ASSERT_LE(Abs(-1),2);
    ASSERT_GE(Abs(-1),0);
}

  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

1>、正确测试

正确测试

2>、将第一条语句写成: ASSERT_FALSE(Abs(1) == 1) << “Abs(1)=1”,此时再次测试就会打印出自定义的出错信息了。

错误测试


三、gtest系列之事件机制
“事件” 本质是框架给你提供了一个机会, 让你能在这样的几个机会来执行你自己定制的代码, 来给测试用例准备/清理数据。gtest提供了多种事件机制,总结一下gtest的事件一共有三种:
1、TestSuite事件
需要写一个类,继承testing::Test,然后实现两个静态方法:SetUpTestCase方法在第一个TestCase之前执行;TearDownTestCase方法在最后一个TestCase之后执行。
2、TestCase事件
是挂在每个案例执行前后的,需要实现的是SetUp方法和TearDown方法。SetUp方法在每个TestCase之前执行;TearDown方法在每个TestCase之后执行。
3、全局事件
要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。SetUp方法在所有案例执行前执行;TearDown方法在所有案例执行后执行。
例如全局事件可以按照下列方式来使用:
除了要继承testing::Environment类,还要定义一个该全局环境的一个对象并将该对象添加到全局环境测试中去。

全局事件

下面我们再来做一个测试实例,测试Map的find()和size()函数并通过继承testing::Test来实现。
此时的TEST宏必须写成TEST_F,而且它的第一个参数必须与类名一致,
TEST_F test fixture,测试夹具,测试套,承担了一个注册的功能。
代码实现如下:

class TestMap:public testing::Test
{
public:
    //添加日志
    static void SetUpTestCase()
    {
        cout<<"SetUpTestCase"<<endl;
    }
    static void TearDownTestCase()
    {
        cout<<"TearDownTestCase"<<endl;
    }
    virtual void SetUp()   //TEST跑之前会执行SetUp
    {
        cout<<"SetUp"<<endl;
        test_map.insert(make_pair(1,0));
        test_map.insert(make_pair(2,1));
        test_map.insert(make_pair(3,2));
        test_map.insert(make_pair(4,3));
        test_map.insert(make_pair(5,4));
    }
    virtual void TearDown() //TEST跑完之后会执行TearDown
    {
        cout<<"TearDown"<<endl;
        test_map.clear();
    }
    map<int,int> test_map;
};
TEST_F(TestMap,Find)   //此时使用的是TEST_F宏
{
    map<int,int>::iterator it=test_map.find(1);
    ASSERT_NE(it,test_map.end());
}
TEST_F(TestMap,Size)
{
    ASSERT_EQ(test_map.size(),5);
}

int main(int argc,char *argv[])
{
    testing::InitGoogleTest(&argc, argv);//将命令行参数传递给gtest
    return RUN_ALL_TESTS();   //RUN_ALL_TESTS()运行所有测试案例
}
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

四、gtest系列之死亡测试
这里的”死亡”指的是程序的奔溃。通常在测试的过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序奔溃,这个时候我们就要检查程序是否按照预期的方式挂掉,这也就是所谓的”死亡测试”。
死亡测试所用到的宏:

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

下面我们再来做一个测试实例,测试当程序出问题时候死亡测试如何使用?

死亡测试

五、一个关于gtest的简单例子

#include<iostream>
using namespace std;
#include<gtest/gtest.h>

struct LinkNode
{
    int _data;
    LinkNode *_next;
    LinkNode(const int& data)
        :_data(data)
        ,_next(NULL)
    {}
};

class Link
{
public:
    Link()
        :pHead(new LinkNode(0))
    {}
    void PushBack(const int& data)
    {
        if(pHead == NULL)
            return ;
        LinkNode *newNode=new LinkNode(data);
        if(pHead->_next == NULL){  //第一次插入结点
            pHead->_next=newNode;
        }
        else{  //找到最后一个结点直接尾插
            LinkNode *cur=pHead->_next;
            while(cur->_next){
                cur=cur->_next;
            }
            cur->_next=newNode;
        }
    }

    void PopBack()
    {
        if(pHead == NULL)
            return ;
        LinkNode *cur=pHead;
        LinkNode *prev=NULL;
        while(cur->_next)
        {
            prev=cur;
            cur=cur->_next;
        }
        prev->_next=NULL;
        delete cur;
    }

    LinkNode *FindNode(const int& data)
    {
        if(pHead == NULL)
            return NULL;
        LinkNode *cur=pHead->_next;
        while(cur)
        {
            if(cur->_data == data)
                return cur;
            cur=cur->_next;
        }
        return NULL;
    }

    bool Delete(int data)
    {
        LinkNode *pos=FindNode(data);
        if(pos == NULL)
            return false;
        LinkNode *cur=pHead->_next;
        while(cur->_next != pos)
        {
            cur=cur->_next;
        }
        cur->_next=pos->_next;
        delete pos;
        return true;
    }

    void Destroy()
    {
        if(pHead == NULL)
            return;
        LinkNode *cur=pHead->_next;
        while(cur)
        {
            LinkNode *del=cur;
            cur=cur->_next;
            delete del;
            del=NULL;
        }
        delete pHead;  //删除头结点
    }
    LinkNode *pHead;
};

class TestLink:public testing::Test
{
public:
    virtual void SetUp()
    {
        cout<<"SetUp"<<endl;
        for(int i=1;i<=5;i++){
            link.PushBack(i);
        }
    }
    virtual void TearDown()
    {
        cout<<"TearDown"<<endl;
        link.Destroy();
    }
    Link link;
};

TEST_F(TestLink,PushBack)
{
    ASSERT_FALSE(link.pHead == NULL);
    link.PushBack(9);
    LinkNode *res=link.FindNode(9);
    ASSERT_FALSE(res == NULL);
}

TEST_F(TestLink,PopBack)
{
    for(int i=1;i<=5;i++){
        link.PopBack();
    }
}

TEST_F(TestLink,FindNode)
{
    ASSERT_TRUE(link.FindNode(3));
    ASSERT_TRUE(link.FindNode(2));
    ASSERT_TRUE(link.FindNode(4));
    ASSERT_TRUE(link.FindNode(5));
    ASSERT_TRUE(link.FindNode(1));
    ASSERT_FALSE(link.FindNode(7));
}

TEST_F(TestLink,Delete)
{
    ASSERT_FALSE(link.pHead == NULL);
    ASSERT_TRUE(link.Delete(3) == true);
    ASSERT_TRUE(link.Delete(9) == false);
}

int main(int argc,char *argv[]) { testing::InitGoogleTest(&argc,argv); return RUN_ALL_TESTS(); }
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153

点击此处查看源码

以上测试用例都是在Linux系统下测试的,读者需自行在Linux下安装gtest。
在这里就分享结束了~~~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187807.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 经典汉罗塔问题解决方案[通俗易懂]

    经典汉罗塔问题解决方案[通俗易懂]汉罗塔问题将a的盘子移动到c针且一次只能移动一个盘,在移动过程中必须保持大盘在下,小盘在上。1、将n-1个盘子从a移动到b盘2、将a剩下的一个盘子移动到c盘3、将b的n-1个盘子移动到c盘#include<iostream>usingnamespacestd;voidmove1(chara,charc){ cout<<a<<“–>”<<c<<endl;}voidhanoi(intn,

  • mybatis log Plugin 的激活码_通用破解码

    mybatis log Plugin 的激活码_通用破解码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 镁光闪存颗粒对照表_海力士、南亚、镁光内存颗粒编码解析,妈妈再也不用担心你买内存条了…「建议收藏」

    镁光闪存颗粒对照表_海力士、南亚、镁光内存颗粒编码解析,妈妈再也不用担心你买内存条了…「建议收藏」海力士、南亚、镁光内存颗粒编码解析,妈妈再也不用担心你买内存条了2019-12-1915:19:5740点赞221收藏11评论你是AMDYes党?还是intel和NVIDIA的忠实簇拥呢?最新一届#装机大师赛#开始啦!本次装机阵营赛分为3A红组、intelNVIDIA蓝绿组、混搭组还有ITX组,实体or虚拟装机都能参与,可使用值得买定制化DIY装机工具在文中展现配置单!每个小组均有精美礼品,…

  • python初级:基础知识-字符串

    python初级:基础知识-字符串

  • spark 入门_新手入门

    spark 入门_新手入门一Spark概述 111什么是Spark 2Spark特点 3Spark的用户和用途 二Spark集群安装 1集群角色 2机器准备 3下载Spark安装包 4配置SparkStandalone 5配置JobHistoryServerStandalone 6配置SparkHAStandalone 7配置SparkYarn …

    2022年10月24日
  • 如何找回被盗的微信号(百分百成功)[通俗易懂]

    如何找回被盗的微信号(百分百成功)[通俗易懂]见到这篇文章的小伙伴,可能是被领皮肤、送福利等诱导活动被走微信号,这帮不法分子把骗取你们的微信号,以300-1000不等价格卖给黑色产业链,如果不法分子利用你的微信号去做违法的事情,警察也会查到你,因为你的微信号是实名认证了的。如果你的微信号有钱财也会被盗刷走。(请大家保护好自己微信号,不要轻易把微信帐号+密码+手机等给别人)记住:只要是你的实名微信号,就一定可以找回来,现在小编就教大家如何找回第一步:骗子要求你卸载客户端申诉方法第二步:没有卸载微信客户端申诉方法第一步:这是卸载过微信客户端申诉

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号