如何使用Google Test (gtest) 为c++代码编写单元测试? (基础断言)

技术百科 穿越時空 发布时间:2026-01-13 浏览:
c++kquote>ASSERT_失败时终止测试函数,EXPECT_仅记录错误并继续执行;前者用于前置检查,后者用于主体逻辑验证。

gtest 的 ASSERT_* 和 EXPECT_* 有什么区别?

核心区别在失败时的行为:ASSERT_* 是“硬中断”,一旦断言失败,当前测试函数立刻返回,后续语句不执行;EXPECT_* 是“软提示”,失败只记录错误,测试函数继续运行。比如你在验证对象初始化后调用多个成员函数,用 EXPECT_EQ 能一次性看到所有失败点;但若 ptrnullptr 就不该继续解引用,这时该用 ASSERT_NE(ptr, nullptr)

常见组合习惯:

  • ASSERT_* 做前置条件检查(如指针非空、文件打开成功)
  • EXPECT_* 做主体逻辑验证(如计算结果、状态值)
  • 避免在循环体内滥用 ASSERT_*,否则可能漏掉后续迭代的错误

如何写一个最简可运行的 gtest 测试用例?

不需要宏定义或复杂配置,只要包含头文件、写 TEST 宏、链接 libgtest 即可运行。注意:gtest 不依赖 main(),它自己提供,所以你的测试文件里不要写自己的 main

#include 

TEST(MathTest, AddPositiveNumbers) { EXPECT_EQ(2 + 3, 5); EXPECT_GT(10, 7); }

int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }

编译命令示例(假设已安装 gtest):

立即学习“C++免费学习笔记(深入)”;

  • g++ -std=c++11 test.cpp -lgtest -lgtest_main -pthread
  • 确保链接 -lgtest_main,它提供了默认 main;如果自己写了 main,就只链 -lgtest
  • 缺少 -pthread 可能导致 segfault 或静默失败

字符串比较出错时为什么 EXPECT_EQ 报错信息看不懂?

EXPECT_EQconst char* 默认做指针比较,不是内容比较。比如 EXPECT_EQ("hello", "hello") 实际比较两个字符串字面量的地址,结果是 false —— 这不是你想要的。

正确做法:

  • EXPECT_STREQ("hello", str.c_str()) 比较 C 风格字符串
  • EXPECT_EQ(std::string("hello"), str)EXPECT_EQ("hello"s, str)(C++14 字符串字面量)让类型推导走 std::string 的重载
  • std::string 成员直接用 EXPECT_EQ 是安全的,因为有对应重载

错误示例触发的报错类似:Expected: "abc" Which is: 0x55e2a1234000 —— 这就是在告诉你,它把字符串当指针打了地址。

测试私有成员或未导出函数怎么办?

gtest 本身不提供反射或友元注入机制。强行测私有函数会破坏封装,也增加维护成本。实际中优先考虑:

  • 通过公有接口间接验证私有逻辑(例如调用 Calculate() 后检查返回值和对象状态)
  • 把关键算法抽成独立的 staticfree 函数,放在头文件中并加 inline,测试时直接调用
  • 极少数必须测私有成员的场景,可在类定义末尾加 friend class TestClassName;,并在测试文件中定义同名测试类(注意命名空间匹配)

别为了测试而改生产代码的访问修饰符,更别用 #define private public 这种 hack —— 它会让编译器跳过访问检查,但可能破坏 ABI 或引发 ODR 违规。


# ai  # 是在  # 放在  # 自己的  # 你在  # 打了  # 多个  # 告诉你  # google  # 不需要  # public  # go  # 循环  # 对象  # c++  # String  # class  # 区别  # 指针  # 字符串  # 接口  # 报错  # 为什么  # Static  # private  # define  # 封装  # 成员函数  # 算法  # 头文件  # 命名空间  # char  # 风格字符串  # const 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部