安装

git clone https://github.com/google/googletest.git
cd googletest
mkdir build
cd build
cmake ..
make
sudo make install

介绍

  • gtest提供了TEST()宏,用来定义测试函数
  • gtest提供了EXPECT_*ASSERT_*两种风格的断言
  • 两种断言的区别:
    • 如果ASSERT_*执行失败了,会导致当前的测试函数立即返回;
    • EXPECT_*如果失败了,并不会导致测试函数返回;
    • 一般推荐用EXPECT_*,除非是某个测试失败后续的测试就没必要再执行则使用ASSERT_*
  • EXPECT_*ASSERT_*常用的有如下断言:
    • EXPECT_TRUE(实际值):测试实际值是否为true
    • EXPECT_FALSE(实际值):测试实际值是否为false
    • EXPECT_EQ(实际值,期待值):测试是否相等
    • EXPECT_NE(实际值,期待值):测试是否不等
    • EXPECT_LT(实际值,期待值):测试实际值是否小于期待值
    • EXPECT_LE(实际值,期待值):测试实际值是否小于等于期待值
    • EXPECT_GT(实际值,期待值):测试实际值是否大于期待值
    • EXPECT_GE(实际值,期待值):测试实际值是否大于等于期待值
    • EXPECT_STREQ(字符串1,字符串2):测试C语言风格字符串是否相等
    • EXPECT_STRNE(字符串1,字符串2):测试C语言风格字符串是否不相等

简单测试

  • add.cpp
#include "gtest/gtest.h"

// 用于测试的函数
int add(int a, int b){
  return a + b;
}

// 第一个测试
TEST(add, first){ // add是测试组的名字,first是测试组的子项名字
  EXPECT_EQ(add(0, 0), 0);
}

// 第二个测试
TEST(add, second){
  EXPECT_EQ(add(1, 2), 3);
}

// 第三个测试
TEST(add, third){
  EXPECT_EQ(add(1, 2), 3);
}

int main (int argc, char *argv[])
{
  // 初始化测试
  ::testing::InitGoogleTest(&argc, argv);
  // 运行并返回所有测试结果
  return RUN_ALL_TESTS();
}
  • 编译
g++ add.cpp -o add -lgtest -lpthread
  • 运行./add
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from add
[ RUN      ] add.first
[       OK ] add.first (0 ms)
[ RUN      ] add.second
[       OK ] add.second (0 ms)
[ RUN      ] add.third
[       OK ] add.third (0 ms)
[----------] 3 tests from add (0 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 3 tests.

在测试函数之间共享数据

我们经常会有一些测试是条件几乎全部一致,仅仅只是测试的数据不一样而已,gtest允许在同一组测试中使用初始化,然后本组中的测试子项可以修改变量的数据而不会影响到其他测试子项。接下来我们以leetcode的第一道题TwoSum为例说明:

  • 001_twoSum.cpp
#include <iostream>
#include <vector>
#include "gtest/gtest.h"

using namespace std;

class Solution{
  public:
  vector<int> twoSum(vector<int>& nums, int target){
    for (int i=0; i<nums.size(); i++){
      for (int j=i+1; j<nums.size(); j++){
        if (nums[i] + nums[j] == target){
          return {i, j};
        }
      }
    }
    return {};
  }
};

// 定义一个继承自testing::Test的类
class TwoSumTest:public testing::Test{
  protected:
    // 在protected下定义一个SetUp()的函数,并初始化一些数据
    // 当然有SetUp()就有TearDown()函数用于清理,此处没有清理
    void SetUp(){
      nums = {2, 7, 11, 15};
      target = 9;
      result = {0, 1};
    }
    // 声明需要使用的变量为类的成员
    Solution s;
    vector<int> nums;
    int target;
    vector<int> result;
};

// 使用初始化需要使用TEST_F宏,而不是TEST宏
// 第一个参数必须要与上述定义的类TwoSumTest名字相同
// default同样是TwoSumTest测试组的第一个测试子项
TEST_F(TwoSumTest, default){
  EXPECT_EQ(s.twoSum(nums, target), result);
}

// 第二个测试子项,直接修改初始化变量的值即可
TEST_F(TwoSumTest, second){
  nums = {3, 2, 4};
  target = 6;
  result = {1, 2};
  EXPECT_EQ(s.twoSum(nums, target), result);
}

// 第三个测试子项
TEST_F(TwoSumTest, third){
  nums = {3, 3};
  target = 6;
  result = {0, 1};
  EXPECT_EQ(s.twoSum(nums, target), result);
}

int main (int argc, char *argv[])
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
  • 编译
g++ 001_twoSum.cpp -o 001_twoSum -lgtest -lpthread
  • 运行./001_twoSum
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from TwoSumTest
[ RUN      ] TwoSumTest.default
[       OK ] TwoSumTest.default (0 ms)
[ RUN      ] TwoSumTest.second
[       OK ] TwoSumTest.second (0 ms)
[ RUN      ] TwoSumTest.third
[       OK ] TwoSumTest.third (0 ms)
[----------] 3 tests from TwoSumTest (0 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 3 tests.