1. 一个好的测试
- 测试应该是独立的和可重复的。调试一个由于其他测试而成功或失败的测试是一件痛苦的事情。
googletest通过在不同的对象上运行测试来隔离测试。当测试失败时,googletest允许您单独运行
它以快速调试。 - 测试应该很好地“组织”,并反映出测试代码的结构。googletest将相关测试分组到可以共享数据和
子例程的测试套件中。这种通用模式很容易识别,并使测试易于维护。当人们切换项目并开始在新
的代码库上工作时,这种一致性尤其有用。 - 测试应该是“可移植的”和“可重用的”。谷歌有许多与平台无关的代码;它的测试也应该是平台中立
的。googletest可以在不同的操作系统上工作,使用不同的编译器,所以googletest测试可以在多
种配置下工作。 - 当测试失败时,他们应该提供尽可能多的关于问题的“信息”。谷歌测试不会在第一次测试失败时停
止。相反,它只停止当前的测试并继续下一个测试。还可以设置报告非致命失败的测试,在此之后
当前测试将继续进行。因此,您可以在一个运行-编辑-编译周期中检测和修复多个错误。 - 测试框架应该将测试编写者从日常琐事中解放出来,让他们专注于测试“内容”。Googletest自动跟
踪所有定义的测试,并且不要求用户为了运行它们而枚举它们。 - 测试应该是“快速的”。使用googletest,您可以在测试之间重用共享资源,并且只需要为设置/拆除
支付一次费用,而无需使测试彼此依赖
2. 环境准备
下载:
git clone https://github.com/google/googletest.git
# 或者
wget https://github.com/google/googletest/releases/tag/release-1.11.0
安装:
cd googletest
cmake CMakeLists.txt
make
sudo make install
重要的文件:
googletest
头文件: #include “gtest/gtest.h”
链接静态库: libgtest.a libgtest_main.a
当不想写main函数的时候,可以直接链接到libgtest_main.a
g++ sample.cc -o sample -lgtest -lgtest_main -lpthread
g++ sample.cc -o sample -lgmock -lgmock_main -lpthread
或者自己有main函数:
g++ sample.cc -o sample -lgtest -lpthread
googlemock
头文件: #include “gmock/gmock.h”
静态库文件: libgmock.a libgmock_main.a
3 断言
googletest中大量使用断言来决定测试的成败,所以我们有必要了解这些断言的含义。断言成对出现,它们测试相同的东西,但对当前函数有不同的影响。 ASSERT_ 版本在失败时产生致命失败,并中止当前函数。 EXPECT_ 版本生成非致命失败,它不会中止当前函数。通常首选EXPECT_ ,因为它们允许在测试中报告一个以上的失败。但是,如果在有问题的断言失败时继续没有意义,则应该使用 ASSERT_* 。所有断言宏都支持输出流,也就是当出现错误的时候,我们可以通过流输出更详细的信息;注意编码问题,经流输出的信息会自动转换为 UTF-8;
致命断言 | 非致命断言 | 验证 |
---|---|---|
ASSERT_TRUE(condition); | EXPECT_TRUE(condition); | condition 是 true |
ASSERT_FALSE(condition); | EXPECT_FALSE(condition); | condition 是 false |
二元比较
这个部分描述比较两个值的断言。
致命断言 非致命断言 验证
致命断言 | 非致命断言 | 验证 | |
---|---|---|---|
ASSERT_EQ(val1, val2); | EXPECT_EQ(val1, val2); | val1 == val2 | |
ASSERT_NE(val1, val2); | EXPECT_NE(val1, val2); | val1 != val2 | |
ASSERT_LT(val1, val2); | EXPECT_LT(val1, val2); | val1 < val2 | |
ASSERT_LE(val1, val2); | EXPECT_LE(val1, val2); | val1 <= val2 | |
ASSERT_GT(val1, val2); | EXPECT_GT(val1, val2); | val1 > val2 | |
ASSERT_GE(val1, val2); | EXPECT_GE(val1, val2); | val1 >= val2 |
当可能时,ASSERT_EQ(actual, expected)
好于 ASSERT_TRUE(actual == expected)
,因为它在失败时告诉你 actual
和 expected
的值。ASSERT_EQ()
对指针执行相等性操作。如果使用两个 C 字符串,它测试它们是否位于相同的内存位置,而不是它们是否具有相同的值。因此,如果你想比较 C 字符串的值(比如 const char*
),使用 ASSERT_STREQ()
,特别地,要断言 C 字符串是 NULL
,则使用 ASSERT_STREQ(c_string, NULL)
,如果支持 c++11 则考虑使用 ASSERT_EQ(c_string, nullptr)
。要比较两个 string
对象,你应该使用 ASSERT_EQ
。当执行指针比较时使用 *_EQ(ptr, nullptr)
和 *_NE(ptr, nullptr)
而不是 *_EQ(ptr, NULL)
和 *_NE(ptr, NULL)
。这是因为 nullptr
是类型安全的而 NULL
不是。