【ros2学习记录3】gtest下载及常见用法

前言:gtest中事件的结构层次

在这里插入图片描述

测试程序:一个测试程序只有一个main函数,也可以说是一个可执行程序是一个测试程序。该级别的事件机制会在程序的开始和结束执行。

测试套件:代表一个测试用例的集合体,该级别的事件机制会在整体的测试案例开始可结束执行。

测试用例:该级别的事件机制会在每个测试用例开始和结束都执行。

1、TEST

TEST(TestCaseName, TestName)

TestCaseNmae为测试用例名,TestName为测试名
在最终终端输出的测试结构中会给出TestCaseNmae.TestName的测试说明
//for example
TEST(FactorialTest,Negative)
{
	EXPECT_EQ(1.Factorial(-5);
}

TEST(FactorialTest,Zero)
{
	EXPECT_EQ(1.Factorial(0);
}

TEST(FactorialTest,Positive)
{
	EXPECT_EQ(2.Factorial(2);
}

在这里插入图片描述

2、EXPECT_* 和ASSERT_* 的异同

//相同之处
{ASSERT|EXPECT}_EQ(expected,actual): Tests that expected == actual

{ASSERT|EXPECT}_NE(v1,v2):           Tests that v1 != v2

{ASSERT|EXPECT}_LT(v1,v2):           Tests that v1 < v2

{ASSERT|EXPECT}_LE(v1,v2):           Tests that v1 <= v2

{ASSERT|EXPECT}_GT(v1,v2):           Tests that v1 > v2

{ASSERT|EXPECT}_GE(v1,v2):           Tests that v1 >= v2
//不同之处
(1)EXPECT_*失败时,案例继续往下执行;
(2)ASSERT_*失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行,退出当前函数,并非退出当前案例。

3、获取参数化

(1)、添加类

// 继承自public::testing::TestWithParam<T>
class IsPrimeParamTest : public::testing::TestWithParam<int>
{

};

(2)、告知gtest测试参数

INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));
第一个参数是测试案例的前缀,可以任意取。
第二个参数是测试案例的名称,需要和之前定义的参数化的类的名称相同
第三个参数是可以理解为参数生成器,上面的例子使用test::Values表示使用括号内的参数。
   还可以是:Range(begin,end[,step]
           ValuesIn(容器和c数组) ValuesIn(begin,end)
           Bool()分别取truefalse
           combine(g1,g2,...,gn)排列组合

(3)、获取参数并测试

TEST_P(IsPrimeParamTest, HandleTrueReturn)
{
   	 int n =  GetParam();
     EXPECT_TRUE(IsPrime(n));
}

4、事件机制

(1)、全局事件机制(针对整个测试程序)

实现全局的事件机制,需要创建一个自己的类,继承testing::Environment类.
然后分别实现成员函数SetUp()和TearDown(),同时在main函数内进行调用,即"testing::AddGlobalTestEnvironment(new MyEnvironment);",通过调用函数我们可以添加多个全局的事件机制。

SetUp()函数是在所有测试开始前执行。
TearDown()函数是在所有测试结束后执行。
#include <iostream>

#include <gtest/gtest.h>

using namespace std;

class MyEnvironment0 : public testing::Environment
{
    public:
        virtual void SetUp()
        {
            cout << "Global event0 : start" << endl;
        }

        virtual void TearDown()
        {
            cout << "Global event0 : end" << endl;
        }
};

class MyEnvironment1 : public testing::Environment
{
    public:
        virtual void SetUp()
        {
            cout << "Global event1 : start" << endl;
        }

        virtual void TearDown()
        {
            cout << "Global event1 : end" << endl;
        }
};

TEST(GlobalTest0, test0)
{
    EXPECT_EQ(1, 1);
};


TEST(GlobalTest0, test1)
{
    EXPECT_EQ(2, 2);
};

TEST(GlobalTest1, test0)
{
    EXPECT_EQ(3, 3);
};

int main(int argc, char *argv[])
{
    testing::AddGlobalTestEnvironment(new MyEnvironment0);
    testing::AddGlobalTestEnvironment(new MyEnvironment1);

    testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}

在这里插入图片描述

(2)、局部事件机制(针对测试套件)

测试套件的事件机制我们同样需要去创建一个类,继承testing::Test,实现两个静态函数SetUpTestCase()和TearDownTestCase(),
测试套件的事件机制不需要像全局事件机制一样在main注册,而是需要将我们平时使用的TEST宏改为TEST_F宏。

SetUpTestCase()函数是在测试套件第一个测试用例开始前执行。
TearDownTestCase()函数是在测试套件最后一个测试用例结束后执行。

⭐注意TEST_F的第一个参数使我们创建的类名,也就是当前测试套件的名称。
⭐静态函数补充(https://blog.csdn.net/m0_61822314/article/details/126274782?spm=1001.2014.3001.5502)
#include <iostream>

#include <gtest/gtest.h>

using namespace std;

class MyTestSuite0 : public testing::Test
{
    protected:
        static void SetUpTestSuite()
        {
            cout << "TestSuite event0 : start" << endl;
        }

        static void TearDownTestSuite()
        {
            cout << "TestSuite event0 : end" << endl;
        }
};

class MyTestSuite1 : public testing::Test
{
    protected:
        static void SetUpTestSuite()
        {
            cout << "TestSuite event1 : start" << endl;
        }

        static void TearDownTestSuite()
        {
            cout << "TestSuite event1 : end" << endl;
        }
};

TEST_F(MyTestSuite0, test0)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestSuite1, test0)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestSuite0, test1)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestSuite1, test1)
{
    EXPECT_EQ(1, 1);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}

在这里插入图片描述

(3)、个体事件机制(针对测试用例)

测试用例的事件机制的创建和测试套件的基本一样。
不同地方在于测试用例实现的两个函数分别是SetUp()和TearDown(),这两个函数不是静态函数了。

SetUp()函数是在一个测试用例的开始前执行。
TearDown()函数是在一个测试用例的结束后执行。
#include <iostream>

#include <gtest/gtest.h>

using namespace std;

class MyTestCase0 : public testing::Test
{
    protected:
        virtual void SetUp()
        {
            cout << "TestCase event0 : start" << endl;
        }

        virtual void TearDown()
        {
            cout << "TestCase event0 : end" << endl;
        }
};

class MyTestCase1 : public testing::Test
{
    protected:
        virtual void SetUp()
        {
            cout << "TestCase event1 : start" << endl;
        }
        virtual void TearDown()
        {
            cout << "TestCase event1 : end" << endl;
        }
};

TEST_F(MyTestCase0, test0)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestCase0, test1)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestCase1, test0)
{
    EXPECT_EQ(1, 1);
}

TEST_F(MyTestCase1, test1)
{
    EXPECT_EQ(1, 1);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}

在这里插入图片描述
⭐如何选择事件机制:①setup teardown 内部调用时机②不同事件类的成员变量的生命周期

5、死亡测试

“死亡测试”用于测试程序是否会按照预期的方式崩溃。

(1)死亡测试常用宏

ASSERT_DEATH(statement, regex);
EXPECT_DEATH(statement, regex);	

ASSERT_EXIT(statement, predicate, regex);	
EXPECT_EXIT(statement, predicate, regex);

//example one
TEST(FooDeathTest, Demo)
{
    EXPECT_DEATH(Foo(), "");
}
//example two
TEST(ExitDeathTest, Demo)
{
    EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1),  "");
}

(2)编写死亡测试时,在测试中第一个参数以 “DeathTest”为结尾,运行测试时会优先于其他测试用例

//for example 
TEST(FooDeathTest, demo2){

    EXPECT_DEATH(Foo(),"");
    cout<<"DeathTest........"<<endl;
}

(3)ASSERT || EXPECT_EXIT(statement, predicate, regex)

statement是被测试的代码语句
predicate 在这里必须是一个委托,接收int型参数,并返回bool。只有当返回值为true时,死亡测试案例才算通过。gtest提供了一些常用的predicate:
regex是一个正则表达式,用来匹配异常时在stderr中输出的内容。这里, 要说明的是,*_DEATH其实是对*_EXIT进行的一次包装,*_DEATH的predicate判断进程是否以非0退出码退出或被一个信号杀死。

testing::ExitedWithCode(exit_code)。如果程序正常退出并且退出码与exit_code相同则返回 true
testing::KilledBySignal(signal_number) 
// Windows下不支持。如果程序被signal_number信号kill的话就返回true
// for example
TEST(ExitDeathTest, Demo)
{
    EXPECT_EXIT(_exit(1),  testing::ExitedWithCode(1),  "");
}

5、Linux中gtest下载(附cmake下载)

cmake下载

sudo apt-get install cmake

sudo apt-get install gcc
sudo apt-get install g++

gtest下载

sudo apt-get install cmake

sudo apt-get install gcc
sudo apt-get install g++
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值