学习gtest测试
单元:函数、类等
gtest是一个跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)C++单元测试框架,由google公司发布。gtest是为在不同平台上为编写C++测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。
git clone https://github.com/google/googletest.git
cd googletest
mkdir build
cd build
cmake ..
make && make install
#如果想测试gtest中sample的例子,需要开启
cmake .. -Dgtest_build_samples=ON
make && make install gtest_build_samples=ON
// gtest_sum.cpp
#include <iostream>
#include <gtest/gtest.h>
int sum(int a, int b) {
return a+b;
}
TEST(sum, testSum) {
EXPECT_EQ(5, sum(2, 3)); // 求合2+3=5
EXPECT_NE(3, sum(3, 4)); // 求合3+4 != 3
EXPECT_NE(7, sum(3, 4));
}
// 如果在此处不写main函数,那么在链接库的时候还需要链接-lgtest_main, 否则只需链接-lgtest即可。
#if 0
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#endif
1、首先,测试时使用gtest需包含头文件 gtest/gtest.h, 并链接库 gtest_main.lib 和 gtest.lib。
程序中sum函数是我们要进行测试的函数名或称为分类名。
Test后跟的即为我们要编写的测试方法:
TEST(分类名, 测试名) {
测试代码
也是如何测试,设置测试力
}
2、使用下面套路化的main函数启动测试:
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}//上述代码中也表明,可不写main函数,但需链接 -lgtest_main
3、测试代码含义:
TEST(sum, testSum) {
EXPECT_EQ(5, sum(2, 3)); // 求合2+3=5
EXPECT_NE(3, sum(3, 4)); // 求合3+4 != 3
}
以上面代码段举例,EXPECT_字段的表达的是检查方式,除个别检查外,所有检查都带前缀,在下述两项中二选一:
ASSERT_ : 断言, 不通过检查则中断测试, 当在测试外使用时要求函数返回void。
EXPECT_ : 期望, 不通过检查并不中断测试。
EXPECT和ASSER的区别:
expect遇到错误(false)继续执行
assert遇到错误(false)跳出当前执行
后缀EQ表达的意思「相等」为5 == sum(2,3);
后缀NE表达的意思「不等」为3 !=sum(3,4);
以下列举给test中对数值的测试后缀:
对字符串的检查后缀:
4、编译运行
g++ -o gtest_sum gtest_sum.cpp -lgtest_main -lgtest -lpthread
#include <gtest/gtest.h>
int MAC(int a, int b, int& sum)
{
sum += a*b;
return sum;
}
// 要继承Test这个类,override关键字表示覆盖了基类中的方法
struct Foo:
public ::testing::Test
{
// 设置
virtual void SetUp() override
{
printf("hello");
}
// 拆解
virtual void TearDown() override
{
printf("world");
}
};
// 全局变量
int sideEffect = 42;
// 有副作用的函数: 修改了全局变量真的值
bool f()
{
sideEffect = 16;
return true; // try false
}
TEST(ExampleTest, DemonstrateGtestMacros)
{
const bool result = f();
EXPECT_EQ(true, result) << "hello";
ASSERT_TRUE(true);
}
TEST(test1, testAssert)
{
EXPECT_TRUE(true);
}
TEST(ExampleTests, MAC)
{
int x = 42; int y = 16;
int sum = 100; int oldSum = sum;
int expectedNewSum = oldSum + x*y ;
EXPECT_EQ(
expectedNewSum,
MAC(x, y, sum)
);
EXPECT_EQ(
expectedNewSum,
sum
);
}
1、编译运行
g++ -o ExampleTest ExampleTest.cpp -lgtest_main -lgtest -lpthread
2、一共有三个测试:
测试方法分为四种:基本测试、测试固件、异常测试、值参数化测试
1、基本测试
在最基础的测试中,一般只需要包含头文件gtest.h即可。gtest中常用的所有结构体、类、函数、常量等,都通过命名空间testing访问,但是gtest已经把常用的单元测试功能包装成了带参数宏,所以简单测试中可以忽略命名空间。
Test宏开头便定义了一个可执行测试,其参数为被测函数和自定义测试名称,自定义名称也可为中文,例如TEST(Add, 正数){},{}中添加逻辑代码,形成测试力,测试力要求自拟并利用宏达到自己想要的结果。
每个宏也可以使用 << 运算符在测试失败时输出自定义信息,如:
ASSERT_EQ(M[i], N[j]) << "i = " << i << ", j = " << j;
2、测试固件
测试固件是可以为所有测试创建一个相同的配置环境,并在测试结束后执行清理工作。对测试固件的使用比基本测试多出来的方法是需要继承Test的类:
代码和测试结果如下:
// gtest_sum_AB.cpp
#include <gtest/gtest.h>
class TestSuit1 : public ::testing::Test {
public:
static void TearDownTestCase()
{
std::cout << "TearDownTestCase" << std::endl;
}
static void SetUpTestCase()
{
std::cout << "SetUpTestCase" << std::endl;
}
virtual void SetUp()
{
std::cout << "SetUp" << std::endl;
}
virtual void TearDown()
{
std::cout << "TearDown" << std::endl;
}
};
int testFunc(int a, int b)
{
return a + b;
}
// 注意TEST_F
TEST_F(TestSuit1, testCase1)
{
std::cout << testFunc(1, 3) << std::endl;;
}
TEST_F(TestSuit1, testCase2)
{
std::cout << testFunc(2, 3) << std::endl;;
}
编译运行:
g++ -o gtest_sum_AB gtest_sum_AB.cpp -lgtest_main -lgtest -lpthread
可以看出:
3、异常测试
gtest为异常测试提供了专用的宏:
此异常测试是测试被测对象是否在运行中出现我们测试用例规定的异常:
4、值参数化测试
值参数化测试即为被测对象带入大量随机值进行测试,类似于在for循环内使用函数。
gtest中的定位是使用大量随机值来检验算法实现的正确性,或比较同一个接口的不同实现之间的差别。gtest把“集中输入测试参数”的需求抽象出来提供支持,称为值参数化测试(Value Parameterized Test)。
值参数化测试包括4个步骤:
gtest提供了专门的模板函数来生成参数值序列,如下表所示:
// gtest_addupto.cpp
#include <gtest/gtest.h>
inline unsigned NaiveAddUpTo(unsigned n) {
unsigned sum = 0;
for(unsigned i = 1; i <= n; ++i) sum += i;
return sum;
}
inline unsigned FastAddUpTo(unsigned n) {
return n*(n+1)/2;
}
//参数化测试
class AddUpToTest : public testing::TestWithParam<unsigned>//继承此类进行值参数化测试
{
public:
AddUpToTest() { n_ = GetParam(); } //测试参数由此返回
protected:
unsigned n_;
};
TEST_P(AddUpToTest, Calibration) {
EXPECT_EQ(NaiveAddUpTo(n_), FastAddUpTo(n_)); //期望a和b相等,不中断
}
INSTANTIATE_TEST_CASE_P(
NaiveAndFast, // prefix 前缀
AddUpToTest, // test case name 测试用例名称
testing::Range(1u, 10u) // parameters 参数,u表示unsigned,必需严谨,否则编译错误,
//也可以使用 testing::Range<unsigned>(1, 1000)
);
编译运行:
g++ -o gtest_addupto gtest_addupto.cpp -lgtest_main -lgtest -lpthread