一、GTest简介

GoogleTest是一个单元测试的框架。

单元测试:

单元测试在函数在整个工程运行起来之前,对该函数进行测试,来判断当前函数能否达到预期的效果。

使用GoogleTest:

1.将GoogleTest编译为库;
2.在代码中链接这个库。


二、GTest编译安装

1.源代码编译:
#下载gtest,release-1.8.0
git clone https://github.com/google/googletest
# gtest编译
cd googletest
#生成Makefile文件(先安装cmake,brew install cmake),继续输入命令编译:
cmake CMakeLists.txt
#执行make,生成两个静态库:libgtest.a libgtest_main.a
make
#拷贝到系统目录,注意,如果下诉目录位置在不同版本位置有变动,用find . -name "libgtest*.a" 找到位置
sudo cp libgtest*.a  /usr/lib
sudo cp –a include/gtest/ /usr/include
2.检查是否安装成功

可以写一个简单的测试代码gtest.cpp,如下:

#include<gtest/gtest.h>
int add(int a,int b){return a+b;
}
TEST(testCase,test0){EXPECT_EQ(add(2,3),5);
}
int main(int argc,char **argv){testing::InitGoogleTest(&argc,argv);return RUN_ALL_TESTS();
}

在终端中编译该文件,并运行:

g++ -std=c++11 gtest.cpp -lgtest -lpthread -o gtest.out
./gtest.out

三、GTest使用

单元测试(Unit Test)是对软件基本组成单元(如函数或是一个类的方法)进行的测试,是开发者编写的一小段代码,用于检验被测试代码一个很小的、很明确的功能是否正确。
在gtest中,一个测试用例(test case)可以包含一个或多个测试。一个测试程序可以包含多个测试用例。

可以通过操作符”<<”将一些自定义的信息输出,如:

ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";for (int i = 0; i < x.size(); ++i) {EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}

1.定义测试函数

应用 googletest 编写单元测试时,使用 TEST() 宏来声明测试函数:

TEST(GlobalConfigurationTest, configurationDataTest)

2.断言/宏测试

gtest中,断言是用以检查条件是否为真。

ASSERT_* 版本的断言失败时会产生致命失败,并结束当前函数;
EXPECT_* 版本的断言失败时产生非致命失败,但不会中止当前函数。

3.事件机制

全局事件

要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。

  1. SetUp()方法在所有案例执行前执行

  2. TearDown()方法在所有案例执行后执行

还需要告诉gtest添加这个全局事件,我们需要在main函数中通过testing::AddGlobalTestEnvironment方法将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去。

TestSuite事件

我们需要写一个类,继承testing::Test,然后实现两个静态方法

  1. SetUpTestCase() 方法在第一个TestCase之前执行

  2. TearDownTestCase() 方法在最后一个TestCase之后执行

在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite。

TestCase事件

TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

  1. SetUp()方法在每个TestCase之前执行

  2. TearDown()方法在每个TestCase之后执行


四、例程

1.一个超简单的 googletest 单元测试实例
#include<gtest/gtest.h>
int add(int a,int b){return a+b;
}
TEST(testCase,test0){EXPECT_EQ(add(2,3),5);
}
int main(int argc,char **argv){testing::InitGoogleTest(&argc,argv);return RUN_ALL_TESTS();
}
2.一个较完整的 googletest 单元测试实例
// Configure.h #pragma once
​#include <string> #include <vector>
​class Configure { private: std::vector<std::string> vItems;
​public: int addItem(std::string str);
​std::string getItem(int index);
​int getSize(); };
​// Configure.cpp #include "Configure.h"
​#include <algorithm>
​/** * @brief Add an item to configuration store. Duplicate item will be ignored * @param str item to be stored * @return the index of added configuration item */ int Configure::addItem(std::string str) {
std::vector<std::string>::const_iterator vi=std::find(vItems.begin(), vItems.end(), str); if (vi != vItems.end()) return vi - vItems.begin();
​vItems.push_back(str); return vItems.size() - 1; }
​/** * @brief Return the configure item at specified index. * If the index is out of range, "" will be returned * @param index the index of item * @return the item at specified index */ std::string Configure::getItem(int index) { if (index >= vItems.size()) return ""; else return vItems.at(index); }
​/// Retrieve the information about how many configuration items we have had int Configure::getSize() { return vItems.size(); }
​// ConfigureTest.cpp #include <gtest/gtest.h>
​#include "Configure.h"
​TEST(ConfigureTest, addItem) { // do some initialization Configure* pc = new Configure(); // validate the pointer is not null ASSERT_TRUE(pc != NULL);
​// call the method we want to test pc->addItem("A"); pc->addItem("B"); pc->addItem("A");
​// validate the result after operation EXPECT_EQ(pc->getSize(), 2); EXPECT_STREQ(pc->getItem(0).c_str(), "A"); EXPECT_STREQ(pc->getItem(1).c_str(), "B"); EXPECT_STREQ(pc->getItem(10).c_str(), "");
​delete pc; }

main()函数:

#include <gtest/gtest.h>
​int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv);
​// Runs all tests using Google Test. return RUN_ALL_TESTS(); }

最后,将所有测试代码及main.cpp编译并链接到目标程序中。

此外,在运行可执行目标程序时,可以使用 --gtest_filter 来指定要执行的测试用例,如:

./foo_test 没有指定filter,运行所有测试;
./foo_test --gtest_filter=* 指定filter为*,运行所有测试;
./foo_test --gtest_filter=FooTest.* 运行测试用例FooTest的所有测试;
./foo_test --gtest_filter=*Null*:*Constructor* 运行所有全名(即测试用例名 + “ . ” + 测试名,如 GlobalConfigurationTest.noConfigureFileTest)含有"Null"或"Constructor"的测试;
./foo_test --gtest_filter=FooTest.*-FooTest.Bar 运行测试用例FooTest的所有测试,但不包括FooTest.Bar。

五、我自己学习 googletest 单元测试时写的例程:

//
// Created by toson on 19-3-8.
//
#include <gtest/gtest.h>
#include "shtf_sdk_interface.h"//第一个参数是测试用例名,第二个参数是测试名:随后的测试结果将以"测试用例名.测试名"的形式给出
TEST(FaceImageInit_testCase, FaceImageInit_test){//test dataFaceImage* image = new FaceImage;char errorinfo[256];//生成随机数用于测试srand((unsigned)time(NULL));//测试正数image->width = rand();image->height = rand();image->size = rand();image->bgr = (unsigned char*)rand();cout << "image->width :" << image->width << endl;cout << "image->height:" << image->height << endl;cout << "image->size  :" << image->size << endl;FaceImageInit(image,errorinfo);//断言是否完成程序该完成的功能EXPECT_EQ(image->width, 0);EXPECT_EQ(image->height, 0);EXPECT_EQ(image->size, 0);EXPECT_EQ(image->bgr, nullptr);//测试负数image->width = -rand();image->height = -rand();image->size = -rand();image->bgr = (unsigned char*)-rand();cout << "image->width :" << image->width << endl;cout << "image->height:" << image->height << endl;cout << "image->size  :" << image->size << endl;FaceImageInit(image,errorinfo);EXPECT_EQ(image->width, 0);EXPECT_EQ(image->height, 0);EXPECT_EQ(image->size, 0);EXPECT_EQ(image->bgr, nullptr);delete image;
}int main(int argc,char **argv){testing::InitGoogleTest(&argc,argv); //用来处理Test相关的命令行开关,如果不关注也可不加return RUN_ALL_TESTS();
}/*----------------------------------------------------------*/在测试执行之前,系统会先执行TestEnvironment的SetUp()方法;在所有测试用例执行完之后,系统会执行TestEnvironment的TearDown()方法。另外,我们可以定义任意多个继承自testing::Environment的子类,以实现不同的全局事件。所有的子类的SetUp()按照我们调用testing::AddGlobalTestEnvironment添加它们的先后顺序执行,而TearDown()的执行顺序则与添加顺序相反。
//class ShtfSdkTnterfaceTestEnvironment : public testing::Environment{ //我的全局环境设置
//public:
//    virtual void SetUp() //在所有测试启动之前需要做的操作
//    {
//        ;//std::cout << "Foo FooEnvironment SetUP" << std::endl;
//    }
//    virtual void TearDown() //在所有测试运行结束后需要做的操作
//    {
//        ;//std::cout << "Foo FooEnvironment TearDown" << std::endl;
//    }TestEnvironment(){ //在SetUp()之前cout<<"TestEnvironment()"<<endl;};~TestEnvironment(){ //在TearDown()之后cout<<"~TestEnvironment()"<<endl;};
//};
//
在测试套件的第一个测试用例开始前,SetUpTestCase()函数会被调用,而在测试套件中的最后一个测试用例运行结束后,TearDownTestCase()函数会被调用。
//class TestMap:public testing::Test //套装例子
//{
//public:
//    static void SetUpTestCase() //测试套件的第一个测试用例开始前,SetUpTestCase()函数会被调用
//    {
//        ;//cout<<"SetUpTestCase()"<<endl;
//        s=new Student(23);
//    }
//    static void TearDownTestCase() //在测试套件中的最后一个测试用例运行结束后,TearDownTestCase()函数会被调用
//    {
//        delete s;
//        ;//cout<<"TearDownTestCase()"<<endl;
//    }
//    void SetUp() //测试套件的每次测试用例开始前,SetUp()函数会被调用
//    {
//        ;//cout<<"SetUp(), running"<<endl;
//    }
//    void TearDown() //测试套件的每次测试用例运行结束后,TearDown()函数会被调用
//    {
//        ;//cout<<"TearDown(), stopping"<<endl;
//    }TestMap(){ //在SetUpTestCase()之后,在SetUp()之前cout<<"TestMap()"<<endl;};~TestMap(){ //在TearDown()之后,在SetUpTestCase()之前cout<<"~TestMap()"<<endl;};
//};
//
第一个参数是测试用例名,第二个参数是测试名:随后的测试结果将以"测试用例名.测试名"的形式给出
//TEST_F(TestMap, Test1) //对TestMap进行测试,test1
//{
//    s->print();
//    Student s1(18);
//    s1.print();ASSERT_EQ(s1, (Student *)NULL);ASSERT_NE(s1, (Student )NULL);
//}
//TEST_F(TestMap, Test2) //对TestMap进行测试,test2
//{Student *s1;
//    s->print();ASSERT_NE(Student(23), NULL);ASSERT_NE(s1, (Student *)NULL);
//    ASSERT_EQ(0, 0);
//}
//
//int main(int argc, char** argv)
//{
//    //在RUN_ALL_TESTS()之前,我们调用如下语句:
//    //    testing::AddGlobalTestEnvironment(new GlobalEnvent);
//    //    将这个测试层面的的事件添加到事件列表即可。
//    testing::AddGlobalTestEnvironment(new ShtfSdkTnterfaceTestEnvironment);
//    testing::InitGoogleTest(&argc, argv); //用来处理Test相关的命令行开关,如果不关注也可不加
//    return RUN_ALL_TESTS();
//}

GoogleTest单元测试学习相关推荐

  1. Qt程序单元测试学习记录

      7月比较忙,很少更新博客,上旬任务是给公司原来的程序做简单的单元测试.毕业这两年写过很多代码,从来没有注意过单元测试这东西,现在开始认真对待,开始看别人写的文章来学习.这里记录下最近学到的,以及自 ...

  2. C++单元测试学习总结9

    C++单元测试一:并非看上去那么简单--几个很实际的问题 理想与现实 为Java和C#做单元测试,基本上都有比较统一的工具.模式可用,IDE的支持也非常到位:可是到 了C++这里,一切就变的那样的&q ...

  3. 在CodeBlocks下配置GoogleTest单元测试框架

    环境准备 Windows 10 Code::Blocks 20.03 Google Test 1.7.0 CMake 3.11.0 编译GoogleTest 一.创建一个工作目录D:\gtest,将刚 ...

  4. Android 单元测试学习计划

    网上查了一下Android单元测试相关的知识点,总结了一个学习步骤: 1. 什么是单元测试 2. 单元测试正反面: 2.1. 重要性 2.2. 缺陷 2.3. 策略 3. 单元测试的基础知识: 3.1 ...

  5. googletest单元测试框架安装及使用

    1.下载googletest 介绍:现在的googletest软件包分两部分,一部分是gtest,单元测试框架,实现对单元测试用例的管理和设计,另一部分是gmock,实现打桩功能,这两个可以结合起来使 ...

  6. Android单元测试学习总结

    文章目录 一.本地单元测试 1. 创建测试类 2. Assert类中的常用断言方法 3. 运行测试类 4. 运行单个测试方法或多个测试类 二.Mockito测试框架的使用 1. Mock概念的理解 2 ...

  7. Go单元测试学习笔记 V1.0

    与你相识 博主介绍: – 本人是普通大学生一枚,每天钻研计算机技能,CSDN主要分享一些技术内容,因我常常去寻找资料,不经常能找到合适的,精品的,全面的内容,导致我花费了大量的时间,所以会将摸索的内容 ...

  8. Android单元测试学习之 Junit4

    保持单元测试的独立性,单元测试用例之间绝不能互相调用,也不能依赖执行的先后次序 Repeatable 重复性 单元测试是可以重复执行的,不能收到外界环境的影响,因为单元测试通常会被放到持续集成中,每次 ...

  9. Junit单元测试学习笔记一

    我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数 ...

最新文章

  1. 数字货币 分层确定性钱包(HD Wallets)
  2. oracle怎么判断是裸设备安装,Oracle 9i下以裸设备方式安装数据库
  3. vue3中websocket用法
  4. 文件系统(02):基于SpringBoot框架,管理Xml和CSV文件类型
  5. linux 3d加速驱动_实时Linux,3D打印自行车,Google的“加速的移动页面”等
  6. linux 隐藏显示终端光标
  7. 编程实现 带符号减法溢出判断
  8. .Net中的加密解密
  9. Android开发学习——基础学习
  10. Python内置函数filter(),map(),reduce(),lambda
  11. 安卓手机实现wifi中继、WiFi信号增强
  12. 【超图+CESIUM】【基础API使用示例】34、超图|CESIUM - 绘制光流流光线段
  13. xp计算机共享能否指定用户,XP怎么设置局域网共享?
  14. canvas实现虚线带箭头效果
  15. 机器学习笔记之R语言基础5(T,F检验)
  16. 计算机可以计算出十的一百次方吗,世界上最大的数字单位 古戈尔(1古戈尔等于10的100次方)...
  17. html style属性的用法
  18. EFR32--如何在EFR32程序中修改UUID
  19. 每日格言积累及总结——更新中
  20. mac 下备份同步qq聊天纪录

热门文章

  1. 张朝霞博客,先谈下个人的一些事情,总结自己
  2. win10录屏_一分钟教你学会两种电脑录屏方法,以后别再说不知道了
  3. 浅析Tomcat结构以及自定义嵌入式Tomcat
  4. 树莓派gpio接口编程基础知识
  5. CE修改模拟器里的数据
  6. 顺无盘linux win10包,(2018.05.21)云更新2016正式版x86_2016.10.15.4976无盘xp-win7x32-x64-win10x64公包...
  7. AdaBoost人脸检测算法1(转…
  8. Java中的Comparable接口和Comparator接口
  9. 测试计划与测试方案包括内容
  10. 使用node.js http-server启动了,但是网页打开显示无法正常工作