1. 作用

    1. 作为代码编码人员,写完代码,不仅要保证编译通过和运行,还要保证逻辑尽量正确。单元测试是对软件可测试最小单元的检查和校验。单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。(来自百度百科
    2. 其作用可以归为四种:

      1. 验证:验证程序逻辑的正确性,即使后期升级,通过跑单元测试,也可以看到升级后是否会对旧逻辑有影响
      2. 设计:促使程序员写出可单独测试的代码,从而更容易解耦
      3. 文档:作为程序使用的sample
      4. 回归:应对程序升级,也可以集成到code review之前的编译,自动做回归,典型用法就是在DevOps的编译打包阶段,例如jeckins编译完成后,自动触发单元测试。
    3. gtest是google提供的一套针对C++的单元测试框架,本文主要阐述其原理和使用方法。
    4. 与gtest配套的框架叫gmock,用于打桩,后续有空再写一篇介绍gmock的使用
  2. 原理

    1. gtest主要由一系列的宏和事件实现。
      1. 宏:有TEST和TEST_F宏,TEST宏针对简单的测试用例,TEST_F宏针对需要做初始化和资源回收的测试用例,有点像类似C++的构造函数和析构函数,两个宏都是把参数展开后拼成一个类。
      2. 事件:分为三种事件
        1.   
        2. 测试程序:一个进程,全局事件在该层

        3. 测试套件:一系列测试用例的集合,SetUpTestCase事件在该层(注意,网上很多地方大部分写的是SetUpTestSuite,应该是老版本)

        4. 测试用例:一个测试用例的事件体现在每个用例前后的SetUp和TearDown

        5. 每个事件可用于下级时间的数据共享以及测试前后的数据处理
  3. 使用

    1. 如果时间充足,想整体了解,可以参考wiki
      1. TEST

        TEST(TestSuiteName, TestName) {
        ... statements ...
        }

        会生成TestSuiteName_TestName_,不同的TestSuiteName可以有相同的TestName,需要注意的是所有的名字都不能有下划线

      2. TEST_F
        TEST_F(TestFixtureName, TestName) {
        ... statements ...
        }

        固定的套件名字

      3. TEST_P
        TEST_P(MyTestSuite, DoesSomething) {
        ...
        EXPECT_TRUE(DoSomething(GetParam()));
        ...
        }

        支持传递参数

    2. 事件
      1. 全局事件:需要创建一个自己的类,然后继承testing::Environment类,分别实现成员函数SetUp()和TearDown(),同时在main函数内进行调用,即"testing::AddGlobalTestEnvironment(new MyEnvironment);",通过调用函数我们可以添加多个全局的事件机制。需要注意的是,全局事件在--gtest_repeat参数大于1的情况下(可以通过--help查看其他参数),会执行多次
        1. 代码:

          #include <iostream>
          
          #include <gtest/gtest.h>
          
          using namespace std;
          
          class MyEnvironment0 : public testing::Environment {
          public:
          virtual void SetUp() {
          cout << "Global event0 : start1" << 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(1, 1);
          }; TEST(GlobalTest1, test0) {
          EXPECT_EQ(1, 1);
          }; 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宏
        1. 代码:

          #include <iostream>
          
          #include <gtest/gtest.h>
          
          using namespace std;
          
          class MyTestSuite0 : public testing::Test
          {
          protected:
          // 网上大部分写的是SetUpTestSuite,google后面升级版本了,改成SetUpTestCase
          // 相关讨论:https://stackoverflow.com/questions/54468799/google-test-using-setuptestsuite-doesnt-seem-to-work
          static void SetUpTestCase()
          {
          cout << "TestSuite event0 : start" << endl;
          } static void TearDownTestCase()
          {
          cout << "TestSuite event0 : end" << endl;
          }
          }; class MyTestSuite1 : public testing::Test
          {
          protected:
          static void SetUpTestCase()
          {
          cout << "TestSuite event1 : start" << endl;
          } static void TearDownTestCase()
          {
          cout << "TestSuite event1 : end" << endl;
          }
          }; // 必须用TEST实现,实现上是拼成一个类MyTestSuite0_test0
          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_F(&argc, argv);
          //
          // return RUN_ALL_TESTS();
          //}
      3. 用例事件:测试用例的事件机制的创建和测试套件的基本一样,不同地方在于测试用例实现的两个函数分别是SetUp()和TearDown(),这两个函数不是静态函数了。SetUp()函数是在一个测试用例的开始前执行。TearDown()函数是在一个测试用例的结束后执行。
        1. 代码:

          #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();
          }
  4. 代码

    1. 上传到个人github中:https://github.com/longbozhan/sample/tree/master/gtest
  5. 参考

    1. https://www.shuzhiduo.com/A/n2d9gnDgJD/
    2. https://google.github.io/googletest/

C++单元测试框架gtest使用的更多相关文章

  1. Google单元测试框架gtest之官方sample笔记2--类型参数测试

    gtest 提供了类型参数化测试方案,可以测试不同类型的数据接口,比如模板测试.可以定义参数类型列表,按照列表定义的类型,每个测试case都执行一遍. 本例中,定义了2种计算素数的类,一个是实时计算, ...

  2. Google单元测试框架gtest之官方sample笔记3--值参数化测试

    1.7 sample7--接口测试 值参数不限定类型,也可以是类的引用,这就可以实现对类接口的测试,一个基类可以有多个继承类,那么可以测试不同的子类功能,但是只需要写一个测试用例,然后使用参数列表实现 ...

  3. Google单元测试框架gtest之官方sample笔记4--事件监控之内存泄漏测试

    sample 10 使用event listener监控Water类的创建和销毁.在Water类中,有一个静态变量allocated,创建一次值加一,销毁一次值减一.为了实现这个功能,重载了new和d ...

  4. 简单易懂的单元测试框架-gtest(一)

    简介     gtest是google开源的一个单元测试框架,以其简单易学的特点被广泛使用.该框架以第三方库的方式插入被测代码中.同其他单元测试框架相似,gtest也通过制作测试样例来进行代码测试.同 ...

  5. Google C++单元测试框架---Gtest框架简介(译文)

    一.设置一个新的测试项目 在用google test写测试项目之前,需要先编译gtest到library库并将测试与其链接.我们为一些流行的构建系统提供了构建文件: msvc/ for Visual ...

  6. 简单易懂的单元测试框架-gtest(二)

    简介     事件机制用于在案例运行前后添加一些操作(相当于挂钩函数).目前,gtest提供了三种等级的事件,分别: 全局级,所有案例执行的前后 TestSuite级,某一个案例集的前后 TestCa ...

  7. Google单元测试框架gtest之官方sample笔记1--简单用例

    1.0 通用部分 和常见的测试工具一样,gtest提供了单体测试常见的工具和组件.比如判断各种类型的值相等,大于,小于等,管理多个测试的测试组如testsuit下辖testcase,为了方便处理初始化 ...

  8. Google C++单元测试框架GoogleTest(总)

    之前一个月都在学习googletest框架,对googletest的文档都翻译了一遍,也都发在了之前的博客里,另外其实还有一部分的文档我没有发,就是GMock的CookBook部分:https://g ...

  9. Google C++单元测试框架GoogleTest---GTest的Sample1和编写单元测试的步骤

    如果你还没有搭建gtest框架,可以参考我之前的博客:http://www.cnblogs.com/jycboy/p/6001153.html.. 1.The first sample: sample ...

随机推荐

  1. Rational Rose的安装及使用教程(包括菜单命令解释、操作向导说明、快捷命令说明)

    一.安装教程 我安装时用的是镜像文件,所以安装前需要辅助软件来处理镜像文件.我用到的是UltraISO.UltraISO中文名叫软碟通 是一款功能强大而又方便实用的光盘映像文件的制作/编辑/转换工具, ...

  2. Hive(八)【行转列、列转行】

    目录 一.行转列 相关函数 concat concat_ws collect_set collect_list 需求 需求分析 数据准备 写SQL 二.列转行 相关函数 split explode l ...

  3. Vue相关,Vue生命周期及对应的行为

    先来一张经典图 生命钩子函数 使用vue的朋友们知道,生命周期函数长这样- mounted: function() { } // 或者 mounted() { } 注意点,Vue的所有生命周期函数都是 ...

  4. linux ln用法

    这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件 这是linux中一个非 ...

  5. oracle(查询数据库对象1)

    1 --查询表信息 2 xxx_tables--包含表的基本描述信息和统计信息 3 xxx_tab_columns--包含表中列的描述信息和统计信息 4 xxx_all_tables--包含当前数据库 ...

  6. OC-引用计数器,内存管理,野指针

    总结 全局断点 →-->+-->Add Exception Breakpoint 开启僵尸监听 打开Edit scheme -->Diagnostics-->Enable Zo ...

  7. vue-cli安装记录

    docker安装 docker network rm  mydkdocker network create --subnet=192.168.1.0/24 mydk cat centos-7-x86_ ...

  8. Linux:$i 和 ${i}区别

    例如你要把有个变量的值和其他字符串连接起来,就需要用到{},以明示{}中的是一个变量. 例如: export var1=ABC export var2=var1=${var1} echo $var2 ...

  9. maven高级学习

    上一篇<maven是什么>介绍了最初级的maven学习,今天就趁着周末的大好时光一起学习下maven的高级知识吧. 1.maven工程要导入jar包的坐标,就必须要考虑解决jar冲突 1) ...

  10. 使用jquery刷新页面以及javascript的一些基本函数

    如何使用jquery刷新当前页面 下面介绍全页面刷新方法:有时候可能会用到 1.window.location.reload()刷新当前页面. 2.parent.location.reload()刷新 ...