拓冰建站拓冰建站
首页 / 资讯中心 / 正文

GoogleTest 断言宏全面参考:在 yaml-cpp 测试中系统掌握 EXPECT_ 与 ASSERT_ 断言体系

GoogleTest 断言宏全面参考在 yaml-cpp 测试中系统掌握 EXPECT_ 与 ASSERT_ 断言体系【免费下载链接】yaml-cppA YAML parser and emitter in C项目地址: https://gitcode.com/GitHub_Trending/ya/yaml-cpp本文是 GoogleTest 1.16.0 断言宏Assertions Reference的完整技术参考以 test/googletest-1.16.0/docs/reference/assertions.md 为骨架结合 yaml-cpp 仓库内真实测试代码进行印证与纵深讲解。读完本文你将掌握EXPECT_/ASSERT_两大族系的全部断言宏从布尔、数值、字符串、浮点、异常、谓词、HRESULT 到死亡断言并能在 yaml-cpp 这类 C 库的单元测试中熟练选用、写出可读且诊断信息丰富的断言。断言体系总览EXPECT_ 与 ASSERT_ 两大族系使用所有断言宏前需要在测试文件中包含头文件#include gtest/gtest.hGoogleTest 的大多数断言宏都以成对形式提供一个EXPECT_变体和一个ASSERT_变体二者在失败时的行为截然不同EXPECT_*非致命失败断言失败时记录一条失败信息但允许当前函数继续执行。适合一个测试内有多处可独立校验的断言的场景失败后仍能收集后续断言的更多信息。ASSERT_*致命失败断言失败时立即中止当前函数的执行。适合后续代码依赖前置条件成立的场景例如指针非空、对象已正确初始化后再访问其成员。以 yaml-cpp 的 test/integration/emitter_test.cpp 为例ASSERT_FALSE(out.good())失败即直接返回因为后续输出out.c_str()只有在 emitter 状态异常时才需要被打印此时继续执行没有意义ASSERT_FALSE(out.good()) Emitter cleanly produced: out.c_str();向断言流式传输自定义失败信息所有断言宏都支持通过运算符向宏中追加自定义失败信息EXPECT_TRUE(my_condition) My condition is not true;任何能够流式输出到ostream的对象都可以流式传入断言宏——特别是 C 字符串const char*和std::string对象。如果向断言中流式传入宽字符串wchar_t*、WindowsUNICODE模式下的TCHAR*或std::wstring打印时会自动转换为 UTF-8 编码。yaml-cpp 的 emitter 测试就大量使用这种技巧例如 Emitter cleanly produced: out.c_str()在断言失败时把 emitter 的完整输出一并呈现极大提升排错效率。显式成功与失败断言这一类断言不校验任何值或表达式而是直接产生成功或失败结果。它们适用于由控制流而非布尔表达式决定测试成败的场景例如switch分支中无法落入任何已知分支时必须报告失败switch(expression) { case 1: ... some checks ... case 2: ... some other checks ... default: FAIL() We shouldnt get here.; }SUCCEED()SUCCEED()直接产生一条成功记录。注意它并不会让整个测试自动成功——一个测试只有在执行过程中没有任何断言失败时才被视为成功。SUCCEED目前纯粹是文档性质的标记不产生任何用户可见输出未来 GoogleTest 可能会在输出中加入SUCCEED消息。FAIL()FAIL()直接产生一个致命失败立即从当前函数返回。因为它会中止当前函数所以只能在返回void的函数中使用。关于断言的放置位置限制参见 test/googletest-1.16.0/docs/advanced.md#assertion-placement例如不要在带返回值的辅助函数中直接FAIL()除非该函数返回void。ADD_FAILURE()ADD_FAILURE()直接产生一个非致命失败当前函数继续运行。与FAIL()形成对照它相当于人工制造一个可恢复的断言失败。ADD_FAILURE_AT(file_path, line_number)ADD_FAILURE_AT(file_path,line_number)在指定的文件与行号处产生一个非致命失败。这在测试框架包装层如自定义的测试辅助函数中希望把失败定位到调用方源码位置而非辅助函数内部非常有用。广义断言EXPECT_THAT 与匹配器EXPECT_THAT(value, matcher) ASSERT_THAT(value, matcher)EXPECT_THAT/ASSERT_THAT校验value是否匹配matcher匹配器。匹配器体系来自 test/googletest-1.16.0/docs/reference/matchers.md使用前需要包含#include gmock/gmock.h一个经典示例——校验字符串前缀、正则匹配以及数值范围using ::testing::AllOf; using ::testing::Gt; using ::testing::Lt; using ::testing::MatchesRegex; using ::testing::StartsWith; EXPECT_THAT(value1, StartsWith(Hello)); EXPECT_THAT(value2, MatchesRegex(Line \\d)); ASSERT_THAT(value3, AllOf(Gt(5), Lt(10)));匹配器让断言读起来像自然语言并生成信息丰富的失败消息。例如value1的断言失败时输出类似Value of: value1 Actual: Hi, world! Expected: starts with HelloGoogleTest 内置了丰富的匹配器库见 test/googletest-1.16.0/docs/reference/matchers.md也支持自定义匹配器见 test/googletest-1.16.0/docs/gmock_cook_book.md。EXPECT_THAT因此是一种强大且可扩展的断言形式。该断言的思路借鉴自 Joe Walnes 的 Hamcrest 项目后者为 JUnit 增加了assertThat()。yaml-cpp 中的真实运用在 test/integration/clone_node_test.cpp 中测试节点克隆后 map 的键位置信息时用testing::UnorderedElementsAre校验键的 Mark 集合与预期完全一致、且不依赖键的遍历顺序EXPECT_THAT(key_marks, testing::UnorderedElementsAre( ComparableMark(1, 1, 0), ComparableMark(15, 2, 0), ComparableMark(35, 3, 0), ComparableMark(48, 4, 0)));这正是EXPECT_THAT相对手写循环校验的优势集合比较的语义无序、元素逐一匹配直接由匹配器表达代码意图一目了然。布尔条件断言EXPECT_TRUE(condition) / ASSERT_TRUE(condition) EXPECT_FALSE(condition) / ASSERT_FALSE(condition)EXPECT_TRUE校验condition为真EXPECT_FALSE校验condition为假。yaml-cpp 中的真实运用布尔断言常配合节点的类型与状态查询。例如 test/integration/load_node_test.cpp 用EXPECT_TRUE(node.IsNull())校验~被解析为空节点test/integration/clone_node_test.cpp 则用致命版本的ASSERT_TRUE(sequence_key)确保确实存在序列键这一前置条件成立后才继续对sequence_key[0]、sequence_key[1]等下标解引用——若前置不成立就继续访问会引发空指针/无效节点解引用因此必须用ASSERT_而非EXPECT_ASSERT_TRUE(sequence_key); EXPECT_EQ(sequence_key[0].Mark(), ComparableMark(49, 4, 1)); EXPECT_EQ(sequence_key[1].Mark(), ComparableMark(52, 4, 4));这是ASSERT_致命失败语义的教科书级用例后续断言依赖前置条件。二元比较断言下列断言比较两个值参数必须能够被对应比较运算符比较否则会产生编译错误EXPECT_EQ(val1, val2) / ASSERT_EQ(val1, val2) // val1 val2 EXPECT_NE(val1, val2) / ASSERT_NE(val1, val2) // val1 ! val2 EXPECT_LT(val1, val2) / ASSERT_LT(val1, val2) // val1 val2 EXPECT_LE(val1, val2) / ASSERT_LE(val1, val2) // val1 val2 EXPECT_GT(val1, val2) / ASSERT_GT(val1, val2) // val1 val2 EXPECT_GE(val1, val2) / ASSERT_GE(val1, val2) // val1 val2打印与求值语义若参数支持运算符断言失败时会调用它打印该参数否则 GoogleTest 会尽力以最佳方式打印参见 test/googletest-1.16.0/docs/advanced.md#teaching-googletest-how-to-print-your-values。参数总是恰好求值一次因此参数带副作用是允许的但参数的求值顺序未定义程序不应依赖任何特定的求值顺序。这些断言同时支持窄字符串对象和宽字符串对象std::string与std::wstring。比较浮点数请使用下文 浮点比较断言避免舍入误差导致的假失败。指针与 NULL 的特殊处理EXPECT_EQ/EXPECT_NE对指针做的是指针相等性判断。如果用于两个 C 字符串它比较的是二者是否位于同一内存位置而不是内容是否相等——比较 C 字符串内容应使用EXPECT_STREQ。比较指针与NULL时应写EXPECT_EQ(ptr, nullptr)而不是EXPECT_EQ(ptr, NULL)。yaml-cpp 中的真实运用二元比较断言是 yaml-cpp 测试的主力。仅 test/integration/load_node_test.cpp 一个文件中就出现了 123 处EXPECT_断言其中绝大多数是EXPECT_EQ。例如 test/integration/load_node_test.cpp 校验节点访问的默认值回退逻辑TEST(LoadNodeTest, FallbackValues) { YAML::Node node YAML::Load(foo: bar); EXPECT_EQ(bar, node[foo].asstd::string()); EXPECT_EQ(bar, node[foo].asstd::string(hello)); EXPECT_EQ(hello, node[baz].asstd::string(hello)); EXPECT_EQ(2, node[x].asint()); EXPECT_EQ(2, node[x].asint(5)); EXPECT_EQ(5, node[y].asint(5)); }注意 yaml-cpp 测试中统一采用EXPECT_EQ(期望值, 实际值)的参数顺序这与 GoogleTest 失败消息中Expected/Actual的显示顺序一致能让失败信息更易读。在 test/integration/node_spec_test.cpp 中EXPECT_断言更是多达 523 处覆盖节点类型、标记Mark、迭代等方方面面test/fptostring_test.cpp 则用EXPECT_EQ(34.34, FpToString(34.34))校验浮点转字符串的精确输出。C 字符串比较断言下列断言比较两个C 字符串const char*。要比较两个std::string对象应改用EXPECT_EQ/EXPECT_NE。这些断言同样接受宽 C 字符串wchar_t*如果两个宽字符串比较失败其值会以 UTF-8 窄字符串形式打印。EXPECT_STREQ(str1, str2) / ASSERT_STREQ(str1, str2) // 内容相同 EXPECT_STRNE(str1, str2) / ASSERT_STRNE(str1, str2) // 内容不同 EXPECT_STRCASEEQ(str1, str2) / ASSERT_STRCASEEQ(...) // 内容相同忽略大小写 EXPECT_STRCASENE(str1, str2) / ASSERT_STRCASENE(...) // 内容不同忽略大小写EXPECT_STREQ校验两个 C 字符串内容相同EXPECT_STRNE校验内容不同EXPECT_STRCASEEQ/EXPECT_STRCASENE则在比较时忽略大小写。把 C 字符串与NULL比较时使用EXPECT_EQ(c_string, nullptr)或EXPECT_NE(c_string, nullptr)。实战提示yaml-cpp 测试中 emitter 输出、标签解析等场景若涉及裸字符指针应优先使用EXPECT_STREQ族而非EXPECT_EQ否则会退化为指针地址比较。浮点比较断言由于舍入误差两个浮点值几乎不可能精确相等因此EXPECT_EQ不适合浮点比较。一般而言有意义的浮点比较需要用户仔细选择误差界。GoogleTest 还提供了基于ULPUnits in the Last Place最后一位单位的默认误差界断言。EXPECT_FLOAT_EQ(val1, val2) / ASSERT_FLOAT_EQ(val1, val2) EXPECT_DOUBLE_EQ(val1, val2) / ASSERT_DOUBLE_EQ(val1, val2)EXPECT_FLOAT_EQ校验两个float值近似相等允许相差4 个 ULP。无穷大与最大有限 float 值被视为相隔 1 个 ULP。EXPECT_DOUBLE_EQ校验两个double值近似相等同样允许相差 4 个 ULP。EXPECT_NEAR绝对误差界比较EXPECT_NEAR(val1, val2, abs_error) / ASSERT_NEAR(val1, val2, abs_error)EXPECT_NEAR校验val1与val2之差不超过绝对误差界abs_error。边界语义若两个值都是同号无穷大差视为 0否则若任一方是无穷大差视为无穷大所有非 NaN 的值含无穷大都不被认为会超过abs_error为无穷大的误差界。yaml-cpp 中的真实运用test/integration/load_node_test.cpp 的数值转换测试中先以EXPECT_EQ(1.5f, Load(1.5).asfloat())校验整数值表示的小数再用EXPECT_NE校验 NaN 与自身不相等用EXPECT_EQ与std::numeric_limitsfloat::infinity()校验正负无穷的解析EXPECT_EQ(1.5f, Load(1.5).asfloat()); EXPECT_EQ(1.5, Load(1.5).asdouble()); EXPECT_NE(Load(.nan).asfloat(), Load(.nan).asfloat()); EXPECT_EQ(std::numeric_limitsfloat::infinity(), Load(.inf).asfloat()); EXPECT_EQ(-std::numeric_limitsfloat::infinity(), Load(-.inf).asfloat());这里的EXPECT_NE正是利用了 NaN 不等于自身的 IEEE 754 语义——这也是用断言表达领域语义的范例。凡是涉及浮点解析、发射后回读的测试都应该优先考虑EXPECT_FLOAT_EQ/EXPECT_DOUBLE_EQ/EXPECT_NEAR以规避舍入抖动。异常断言下列断言校验一段代码抛出或不抛出异常使用前提是构建环境启用了异常yaml-cpp 的 CMake 构建默认满足该前提。被测代码可以是复合语句块EXPECT_NO_THROW({ int n 5; DoSomething(n); });EXPECT_THROW(statement, exception_type) / ASSERT_THROW(statement, exception_type) EXPECT_ANY_THROW(statement) / ASSERT_ANY_THROW(statement) EXPECT_NO_THROW(statement) / ASSERT_NO_THROW(statement)EXPECT_THROW校验statement抛出类型为exception_type的异常EXPECT_ANY_THROW校验statement抛出任意类型的异常EXPECT_NO_THROW校验statement不抛出任何异常。yaml-cpp 中的真实运用异常断言在 yaml-cpp 中扮演核心角色因为库本身用异常报告解析错误与类型转换错误。例如 test/integration/load_node_test.cpp 校验把非整数文本转成int必须抛出TypedBadConversionint、越界的int8_t/uint8_t转换必须抛出对应类型转换异常EXPECT_THROW(Load(1.5).asint(), TypedBadConversionint); EXPECT_THROW(Load(128).asint8_t(), TypedBadConversionsigned char); EXPECT_THROW(Load(256).asuint8_t(), TypedBadConversionunsigned char);同文件 test/integration/load_node_test.cpp 还用大量EXPECT_THROW(Load(...), ParserException)断言非法 YAML 输入未闭合引号、非法流式语法foo,bar、空序列流,等必须被解析器拒绝。这验证了EXPECT_THROW是负向测试测试错误路径的标准工具——断言异常类型比简单判断报错了更精确。谓词断言谓词断言允许校验更复杂的谓词同时打印比单独使用EXPECT_TRUE更清晰的失败消息。EXPECT_PRED*直接调用谓词EXPECT_PRED1(pred, val1) ASSERT_PRED1(pred, val1) EXPECT_PRED2(pred, val1, val2) ASSERT_PRED2(pred, val1, val2) EXPECT_PRED3(pred, val1, val2, val3) ASSERT_PRED3(pred, val1, val2, val3) EXPECT_PRED4(pred, val1, val2, val3, val4) ASSERT_PRED4(pred, val1, val2, val3, val4) EXPECT_PRED5(pred, val1, val2, val3, val4, val5) ASSERT_PRED5(pred, val1, val2, val3, val4, val5)pred是接受与宏值参数数量相同参数的函数或仿函数对给定参数返回true则断言成功否则失败。失败时会打印每个参数的值参数总是恰好求值一次。例如// Returns true if m and n have no common divisors except 1. bool MutuallyPrime(int m, int n) { ... } const int a 3; const int b 4; const int c 10; EXPECT_PRED2(MutuallyPrime, a, b); // Succeeds EXPECT_PRED2(MutuallyPrime, b, c); // Fails第二个断言失败时的消息会自动带上每个参数的值MutuallyPrime(b, c) is false, where b is 4 c is 10使用限制与解法如果谓词是重载函数或函数模板宏可能无法确定该用哪个版本需要显式指定函数类型// 重载的 IsPositive()int 与 double 各一个版本 EXPECT_PRED1(static_castbool (*)(int)(IsPositive), 5); EXPECT_PRED1(static_castbool (*)(double)(IsPositive), 3.14); // 直接写 EXPECT_PRED1(IsPositive, 5); 会编译错误模板函数需要显式指定模板实参template typename T bool IsNegative(T x) { return x 0; } EXPECT_PRED1(IsNegativeint, -5); // Must specify type for IsNegative若模板有多个参数用括号把谓词包起来使宏参数解析正确ASSERT_PRED2((MyPredicateint, int), 5, 0);EXPECT_PRED_FORMAT*自定义失败消息格式EXPECT_PRED_FORMAT1(pred_formatter, val1) EXPECT_PRED_FORMAT2(pred_formatter, val1, val2) ... EXPECT_PRED_FORMAT5(pred_formatter, val1, ..., val5) ASSERT_PRED_FORMAT1(pred_formatter, val1) ... ASSERT_PRED_FORMAT5(pred_formatter, val1, ..., val5)pred_formatter是一个谓词格式化器predicate-formatter签名如下testing::AssertionResult PredicateFormatter(const char* expr1, const char* expr2, ... const char* exprn, T1 val1, T2 val2, ... Tn valn);其中val1..valn是谓词参数的值expr1..exprn是这些参数在源码中对应的表达式文本。类型T1..Tn可以是值类型或引用类型若参数类型为T可声明为T或const T。返回值testing::AssertionResult的使用方式参见 test/googletest-1.16.0/docs/advanced.md#using-a-function-that-returns-an-assertionresult。完整示例——自定义两整数互质断言及其失败消息// Returns the smallest prime common divisor of m and n, // or 1 when m and n are mutually prime. int SmallestPrimeCommonDivisor(int m, int n) { ... } bool MutuallyPrime(int m, int n) { ... } // A predicate-formatter for asserting that two integers are mutually prime. testing::AssertionResult AssertMutuallyPrime(const char* m_expr, const char* n_expr, int m, int n) { if (MutuallyPrime(m, n)) return testing::AssertionSuccess(); return testing::AssertionFailure() m_expr and n_expr ( m and n ) are not mutually prime, as they have a common divisor SmallestPrimeCommonDivisor(m, n); } const int a 3; const int b 4; const int c 10; EXPECT_PRED_FORMAT2(AssertMutuallyPrime, a, b); // Succeeds EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c); // Fails最后一个断言失败时产生如下消息自动代入表达式文本b、c与实参值 4、10b and c (4 and 10) are not mutually prime, as they have a common divisor 2EXPECT_PRED_FORMAT*的价值在于失败消息里既能看到源码表达式b、c又能看到实际值4、10还能附加领域化的诊断有一个公共因子 2比EXPECT_TRUE(MutuallyPrime(b, c))的失败输出可读性高一个量级。GoogleTest 自身的 test/googletest-1.16.0/googlemock/test/gmock-cardinalities_test.cc 也大量使用EXPECT_PRED_FORMAT2(IsSubstring, ...)来校验 mock 调用次数文本可作参考。Windows HRESULT 断言下列断言测试HRESULT的成功或失败状态主要用于 Windows 平台 COM 编程生成输出会包含HRESULT对应的人类可读错误消息。例如CComPtrIShellDispatch2 shell; ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(LShell.Application)); CComVariant empty; ASSERT_HRESULT_SUCCEEDED(shell-ShellExecute(CComBSTR(url), empty, empty, empty, empty));EXPECT_HRESULT_SUCCEEDED(expression) / ASSERT_HRESULT_SUCCEEDED(expression) EXPECT_HRESULT_FAILED(expression) / ASSERT_HRESULT_FAILED(expression)EXPECT_HRESULT_SUCCEEDED校验expression是成功状态的HRESULTEXPECT_HRESULT_FAILED校验expression是失败状态的HRESULT。死亡断言死亡断言校验一段代码导致进程终止相关背景参见 test/googletest-1.16.0/docs/advanced.md#death-tests。执行机制死亡断言会新开一个进程并在该进程中执行被测代码具体机制取决于平台与变量::testing::GTEST_FLAG(death_test_style)由命令行参数--gtest_death_test_style初始化POSIX 系统使用fork()Linux 上为clone()生成子进程随后若变量值为fast立即执行死亡测试语句若变量值为threadsafe子进程像最初被调用那样重新执行单元测试二进制但附加额外标志使仅运行当前这一个死亡测试。Windows使用CreateProcess()API 生成子进程并重新执行二进制仅运行当前这一个死亡测试——与 POSIX 的threadsafe模式类似。其他取值非法会导致死亡测试失败。目前该标志的默认值为fast。如果死亡测试语句运行到结束都没有死亡子进程仍会终止此时断言失败。被测代码同样可以是复合语句块EXPECT_DEATH({ int n 5; DoSomething(n); }, Error on line .* of DoSomething());EXPECT_DEATHEXPECT_DEATH(statement, matcher) / ASSERT_DEATH(statement, matcher)校验statement导致进程以非零退出状态终止且产生的stderr 输出匹配matcher。matcher可以是对const std::string的匹配器也可以是正则表达式语法见 test/googletest-1.16.0/docs/advanced.md#regular-expression-syntax——裸字符串s不带匹配器会被当作ContainsRegex(s)处理而不是Eq(s)。例如EXPECT_DEATH(DoSomething(42), My error);该校验调用DoSomething(42)导致进程终止且错误消息包含文本My error。EXPECT_DEATH_IF_SUPPORTEDEXPECT_DEATH_IF_SUPPORTED(statement, matcher) / ASSERT_DEATH_IF_SUPPORTED(statement, matcher)若平台支持死亡测试行为与EXPECT_DEATH完全一致否则不校验任何内容直接通过。GoogleTest 自身的 test/googletest-1.16.0/googlemock/test/gmock-actions_test.cc 中大量使用EXPECT_DEATH_IF_SUPPORTED来测试对非法行为应当崩溃的代码路径同时保持跨平台可移植。EXPECT_DEBUG_DEATHEXPECT_DEBUG_DEATH(statement, matcher) / ASSERT_DEBUG_DEATH(statement, matcher)在调试模式下行为与EXPECT_DEATH相同在非调试模式即定义了NDEBUG下仅执行statement不做任何断言。适合测试仅在assert等调试检查下才会触发的崩溃。EXPECT_EXITEXPECT_EXIT(statement, predicate, matcher) / ASSERT_EXIT(statement, predicate, matcher)校验statement导致进程终止且退出状态满足predicate、stderr 输出匹配matcher。predicate是接受int退出状态并返回bool的函数或仿函数。GoogleTest 提供了两个现成谓词// Returns true if the program exited normally with the given exit status code. ::testing::ExitedWithCode(exit_code); // Returns true if the program was killed by the given signal. // Not available on Windows. ::testing::KilledBySignal(signal_number);matcher的语义与EXPECT_DEATH相同裸字符串按ContainsRegex处理。例如校验NormalExit()打印包含Success的 stderr 消息并以退出码 0 正常退出EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), Success);在 yaml-cpp 中实际编排断言测试工程视角yaml-cpp 仓库把 GoogleTest 1.16.0 作为测试框架内嵌于 test/googletest-1.16.0测试源码则分布在test目录下通过 test/CMakeLists.txt 组织构建测试程序统一由 test/main.cpp 提供入口。断言在其中的分布可以直观看到断言体系的选型规律test/integration/load_node_test.cpp约 123 处EXPECT_以EXPECT_EQ解析值与默认值回退、EXPECT_THROW非法输入必须抛ParserException/TypedBadConversion为绝对主力test/integration/node_spec_test.cpp约 523 处EXPECT_覆盖节点 API 的规格化行为test/integration/clone_node_test.cpp综合使用EXPECT_THAT无序集合匹配、ASSERT_TRUE前置条件与EXPECT_EQ逐项校验并在SCOPED_TRACE(original node)包裹下对克隆前后两轮校验复用同一段检查代码test/fptostring_test.cpp用EXPECT_EQ对浮点转字符串的文本输出做逐字节精确断言。这套分布本身就是一个断言选型最佳实践的活教材数值与状态用EXPECT_EQ族、错误路径用EXPECT_THROW、前置条件用ASSERT_族、复杂集合语义用EXPECT_THAT 匹配器。当你在 yaml-cpp 或任何 C 项目上编写测试时可以对照本文的断言分类结合断言失败时消息的可读性、以及后续代码对前置条件的依赖选择最贴切的断言宏。快速选型速查验证目标推荐断言说明布尔条件EXPECT_TRUE/EXPECT_FALSE简单真假判断数值/对象相等EXPECT_EQ/EXPECT_NE参数恰好求值一次指针按地址比较大小关系EXPECT_LT/LE/GT/GE需满足对应比较运算符C 字符串内容EXPECT_STREQ/EXPECT_STRNE按值比较勿用EXPECT_EQ忽略大小写比较EXPECT_STRCASEEQ/EXPECT_STRCASENE仅限 C 字符串float 近似相等EXPECT_FLOAT_EQ默认 4 ULP 误差界double 近似相等EXPECT_DOUBLE_EQ默认 4 ULP 误差界绝对误差界EXPECT_NEAR需显式给出abs_error抛出指定异常EXPECT_THROWyaml-cpp 解析错误测试的主力抛出任意异常/不抛EXPECT_ANY_THROW/EXPECT_NO_THROW支持复合语句块复杂谓词EXPECT_PRED1..5失败时自动打印各参数值自定义失败消息EXPECT_PRED_FORMAT1..5返回testing::AssertionResult匹配器语义EXPECT_THAT/ASSERT_THAT需包含gmock/gmock.h可扩展进程终止EXPECT_DEATH/EXPECT_EXIT校验 stderr 与退出状态Windows HRESULTEXPECT_HRESULT_SUCCEEDED/FAILED输出人类可读错误消息结语GoogleTest 的断言体系在设计上遵循两条主线EXPECT_非致命与ASSERT_致命的分工以及失败消息必须自解释流式、参数值自动打印、EXPECT_THAT的自然语言语义、EXPECT_PRED_FORMAT的完全定制。yaml-cpp 的数千处测试断言表明一个成熟 C 库的测试几乎会用到断言体系的每个分支——从EXPECT_EQ校验解析结果到EXPECT_THROW锁定错误路径再到EXPECT_THAT表达集合语义。理解并善用这套断言宏是写出可信、可维护、排错高效的单元测试的第一步。【免费下载链接】yaml-cppA YAML parser and emitter in C项目地址: https://gitcode.com/GitHub_Trending/ya/yaml-cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门