目录
- 准备工作
- 测试宏
- 两个概念
- Test Fixtures
- main函数
- 关于线程安全
准备工作
GoogleTest官网:https://google.github.io/googletest/
gtest github仓库:https://github.com/google/googletest
目前最新稳定版本:https://github.com/google/googletest/releases/tag/v1.13.0
下载源码,到目录下创建build文件夹进入后运行 cmake …
测试宏
gtest有两套测试宏:ASSERT_* 和 EXPECT_*:
- ASSERT_* 会生成fatal错误并终止当前函数,EXPECT_* 生成非fatal错误,不会终止当前函数。在使用中优先选择EXPECT_* 。如果发生错误继续测试下去没有意义可以使用ASSERT_*
- ASSERT_* 断言失败后会立即返回,很有可能跳过清理代码,所以有可能发生资源泄露,看使用场景是否允许这种情况发生
两个概念
- test suites
- test fixtures
Test Fixtures
创建一个fixture:
- 继承自::testing::Test,使用protected(因为TEST_F中可以直接访问到继承类中定义的数据成员)
- 可以在类中声明任何想要的对象
- 如果需要可以实现默认构造或者SetUp(),注意不要写成Setup(),使用override关键字可以防止拼写错误
- 如果需要可以实现析构或者TearDown()释放SetUp中申请的资源。在哪些地方使用构造/析构,在哪些地方使用SetUp()/TearDown(),参考https://google.github.io/googletest/faq.html#CtorVsSetUp
当使用fixture时,使用TEST_F()代替TEST(),TEST_F()(_F代表Fixture)允许你在test fixture中访问对象和子程序
TEST_F()的第一个参数必须是 test fixture 的类名,所以必须在使用TEST_F之前定义一个test fixture类
对于每个定义了的TEST_F(),gtest会在运行时创建一个新的test fixture,通过SetUp立即初始化,运行完测试程序后通过TearDown清理,并删除test fixture。注意,在test suite中不同的tests有不同的test fixture对象,gtest会在创建新的test fixture之前先删除以前的。gtest不会在多个tests中复用test fixture。任何一个test的改变不会影响其他的
(TEST和TEST_F要写在cpp中,h和hpp中没法调用)
TEST_F(QueueTest, IsEmptyInitially) {EXPECT_EQ(q0_.size(), 1);
}TEST_F(QueueTest, DequeueWorks) {int *n = q0_.Dequeue();EXPECT_EQ(n, nullptr);n = q1_.Dequeue();ASSERT_NE(n, nullptr);EXPECT_EQ(*n, 1);EXPECT_EQ(q1_.size(), 0);delete n;n = q2_.Dequeue();ASSERT_NE(n, nullptr);EXPECT_EQ(*n, 2);EXPECT_EQ(q2_.size(), 1);delete n;
}
处理流程如下:
- 开始第一个测试(IsEmptyInitially)gtest构造QueueTest对象(我们称之为t1)
- 自动调用 t1.SetUp() 初始化t1
- 执行第一个test的test body
- t1.TearDown()执行清理工作
- t1析构
- 重复第二个test(DequeueWorks)
定义完tests之后,可以运行 RUN_ALL_TESTS(),它会让所有的tests运行。成功返回0,否则返回1。
RUN_ALL_TESTS()运行之后:
- 保存gtest flags的状态
- 为第一个test创建test fixture
- 通过SetUp()初始化
- 在fixture对象上运行test
- 通过TearDown() 清理fixture
- 删除fixture
- 保存gtest flags的状态
- 重复开始下一个test,直到所有的tests都运行完
main函数
对于不需要做额外操作的用户来说应该使用gtest_main代替main。如果要使用main,就需要返回RUN_ALL_TESTS()
int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
::testing::InitGoogleTest() 解析命令行参数,必须要在RUN_ALL_TESTS()前调用,详细信息参考https://google.github.io/googletest/advanced.html
关于线程安全
gtest在pthreads库中被设计为是线程安全的,在其他情况下多线程下是不安全的,大多数情况下断言只在main线程中执行,所以不会有问题,如果要支持多线程安全需要使用gtest-port.h中的同步机制