安装 GTest

1、源代码安装

下载

git clone https://github.com/google/googletest
googletest的目录如下:
image.png

编译

cd googletest
生成 Makefile 文件 (先安装 cmake,brew install cmake),继续输入命令编译:
cmake CMakeLists.txt
执行 make,在文件夹lib下生成两个静态库:
image.png

安装

将所有的gtest库文件拷贝到系统目录,注意,如果lib目录位置在不同版本位置有变动,用 find . -name “libgtest*.a” 找到位置

  1. cd lib
  2. sudo cp libgtest*.a /usr/lib

将gtest的头文件拷贝到系统目录:

  1. cd ../googletest/
  2. sudo cp a include/gtest /usr/include

检查是否安装成功

可以写一个简单的测试代码如下:

  1. #include <gtest/gtest.h>
  2. int add(int a, int b) { return a + b; }
  3. TEST(testCase, test0) { EXPECT_EQ(add(2, 3), 5); }
  4. int main(int argc, char **argv) {
  5. testing::InitGoogleTest(&argc, argv);
  6. return RUN_ALL_TESTS();
  7. }#include<gtest/gtest.h>
  8. int add(int a, int b){
  9. return a+b;
  10. }
  11. TEST(testCase,test0){
  12. EXPECT_EQ(add(2,3),5);
  13. }
  14. int main(int argc, char **argv){
  15. testing::InitGoogleTest(&argc,argv);
  16. return RUN_ALL_TESTS();
  17. }

在该文件的终端输入编译指令:

gqx@gqx-Lenovo-Product:~/workplace/aaaa$ g++ test.cc -lgtest -lpthread

gqx@gqx-Lenovo-Product:~/workplace/aaaa$ ./a.out

即得到如下显示结果:

GTest的安装与使用 - 图3

GTest 的一些基本概念

要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test 会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在 Google Test 的错误信息之后。

断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。ASSERT*版本的断言失败时会产生致命失败,并结束当前函数。EXPECT版本的断言产生非致命失败,而不会中止当前函数。通常更推荐使用 EXPECT_断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用 ASSERT*断言。 因为失败的 ASSERT*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。

GTest 的断言

1、布尔值检查

Fatal assertion Nonfatal assertion Verifies
ASSERTTRUE(_condition); EXPECTTRUE(_condition); condition is true
ASSERTFALSE(_condition); EXPECTFALSE(_condition); condition is false

2、数值型数据检查

Fatal assertion Nonfatal assertion Verifies
ASSERTEQ(_expected, actual); EXPECTEQ(_expected, actual); expected == actual
ASSERTNE(_val1, val2); EXPECTNE(_val1, val2); val1 != val2
ASSERTLT(_val1, val2); EXPECTLT(_val1, val2); val1 < val2
ASSERTLE(_val1, val2); EXPECTLE(_val1, val2); val1 <= val2
ASSERTGT(_val1, val2); EXPECTGT(_val1, val2); val1 > val2
ASSERTGE(_val1, val2); EXPECTGE(_val1, val2); val1 >= val2

3、字符串比较

Fatal assertion Nonfatal assertion Verifies
ASSERTSTREQ(_expected_str, actual_str); EXPECTSTREQ(_expected_str, actual_str); 两个C字符串有相同的内容
ASSERTSTRNE(_str1, str2); EXPECTSTRNE(_str1, str2); 两个C字符串有不同的内容
ASSERTSTRCASEEQ(_expected_str, actual_str); EXPECTSTRCASEEQ(_expected_str, actual_str); 两个C字符串有相同的内容,忽略大小写
ASSERTSTRCASENE(_str1, str2); EXPECTSTRCASENE(_str1, str2); 两个C字符串有不同的内容,忽略大小写

4、异常检查

Fatal assertion Nonfatal assertion Verifies
ASSERTTHROW(_statement, exception_type); EXPECTTHROW(_statement, exception_type); statement throws an exception of the given type
ASSERTANY_THROW(_statement); EXPECTANY_THROW(_statement); statement throws an exception of any type
ASSERTNO_THROW(_statement); EXPECTNO_THROW(_statement); statement doesn’t throw any exception

5、浮点型检查

Fatal assertion Nonfatal assertion Verifies
ASSERTFLOAT_EQ(_expected, actual); EXPECTFLOAT_EQ(_expected, actual); the two float values are almost equal
ASSERTDOUBLE_EQ(_expected, actual); EXPECTDOUBLE_EQ(_expected, actual); the two double values are almost equal

对相近的两个数比较:

Fatal assertion Nonfatal assertion Verifies
ASSERTNEAR(_val1, val2, abs_error); EXPECTNEAR(val1, val2, abserror); the difference between val1 and val2 doesn’t exceed the given absolute error

6、此外还有类型检查、谓词检查等

事件机制

全局事件

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

  1. SetUp() 方法在所有测试案例执行前执行
  2. TearDown() 方法在所有测试案例执行后执行

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

TestSuite 事件

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

方法1

  1. SetUpTestCase() 方法在该类第一个 TestCase 之前执行
  2. TearDownTestCase() 方法在该类最后一个 TestCase 之后执行

方法2

  1. SetUpTestSuite() 方法在该类第一个 TestCase 之前执行
  2. TearDownTestSuite() 方法在该类最后一个 TestCase 之后执行

注意:
方法1和方法2等效,任选其中一种即可。
方法1是遗留的方法,已经不推荐使用,推荐使用方法2.

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

TestCase 事件

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

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

以下案例解决说明上述三个事件的使用

  1. #include <gtest/gtest.h>
  2. #include <iostream>
  3. #include <map>
  4. using namespace std;
  5. class Student {
  6. public:
  7. Student() { age = 0; }
  8. Student(int a) { age = a; }
  9. void print() { cout << "*********** " << age << " **********" << endl; }
  10. private:
  11. int age;
  12. };
  13. class FooEnvironment : public testing::Environment {
  14. public:
  15. virtual void SetUp() {
  16. std::cout << "Foo FooEnvironment SetUP" << std::endl;
  17. }
  18. virtual void TearDown() {
  19. std::cout << "Foo FooEnvironment TearDown" << std::endl;
  20. }
  21. };
  22. static Student *s;
  23. //在第一个test之前,最后一个test之后调用SetUpTestCase()和TearDownTestCase()
  24. class TestMap : public testing::Test {
  25. public:
  26. static void SetUpTestCase() {
  27. cout << "SetUpTestCase()" << endl;
  28. s = new Student(23);
  29. }
  30. static void TearDownTestCase() {
  31. delete s;
  32. cout << "TearDownTestCase()" << endl;
  33. }
  34. void SetUp() { cout << "SetUp() is running" << endl; }
  35. void TearDown() { cout << "TearDown()" << endl; }
  36. };
  37. TEST_F(TestMap, Test1) {
  38. // you can refer to s here
  39. s->print();
  40. }
  41. int main(int argc, char **argv) {
  42. testing::AddGlobalTestEnvironment(new FooEnvironment);
  43. testing::InitGoogleTest(&argc, argv);
  44. return RUN_ALL_TESTS();
  45. }

相关结果和说明如下:

GTest的安装与使用 - 图4

参数化

当考虑多次要为被测函数传入不同的值的情况时,可以按下面的方式去测试。必须添加一个类,继承 testing::TestWithParam。其中 T 就是你需要参数化的参数类型,如下面的案例是 int 型参数。(官方文档上的案例)

  1. #include<gtest/gtest.h>
  2. // Returns true if n is a prime number.
  3. bool IsPrime(int n)
  4. {
  5. // Trivial case 1: small numbers
  6. if (n <= 1) return false;
  7. // Trivial case 2: even numbers
  8. if (n % 2 == 0) return n == 2;
  9. // Now, we have that n is odd and n >= 3.
  10. // Try to divide n by every odd number i, starting from 3
  11. for (int i = 3; ; i += 2) {
  12. // We only have to try i up to the squre root of n
  13. if (i > n/i) break;
  14. // Now, we have i <= n/i < n.
  15. // If n is divisible by i, n is not prime.
  16. if (n % i == 0) return false;
  17. }
  18. // n has no integer factor in the range (1, n), and thus is prime.
  19. return true;
  20. }
  21. class IsPrimeParamTest : public::testing::TestWithParam<int>{};
  22. TEST_P(IsPrimeParamTest, HandleTrueReturn)
  23. {
  24. int n = GetParam();
  25. EXPECT_TRUE(IsPrime(n));
  26. }
  27. //被测函数须传入多个相关的值
  28. INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));
  29. int main(int argc, char **argv)
  30. {
  31. testing::InitGoogleTest(&argc, argv);
  32. return RUN_ALL_TESTS();
  33. }

注:部分内容摘自网络(http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html

原文:https://www.cnblogs.com/helloworldcode/p/9606838.html