GoogleTest 使用指南 | 断言

【C++】GoogleTest入门指南 X_PREDn(fun,v1,v2…):拥有n个参数的函数fun会返回True例如有一个函数equal(a,b),那么就是ASSERT_PRED2(equal,a,b)与ASSERT_EQ、ASSERT_TRUE()这些断言的区别在于输出的错误信息不同,同时它的功能更加强大。 阅读详情

GoogleTest 使用指南 | 断言

ASSERT vs EXPECT

断言的宏可以理解为分为两类,一类是 ASSERT 系列,一类是 EXPECT 系列。

一个直观的解释就是:

  1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。

  2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。

ASSERT_* 示例:

// ASSERT_* - 失败时立即终止当前测试
TEST(AssertTest, StopsOnFailure) {
    ASSERT_EQ(1, 2);  // 失败,下面的代码不会执行
    std::cout << "This won't print" << std::endl;
    ASSERT_EQ(2, 2);  // 不会执行到这里
}

EXPECT_* 示例:

// EXPECT_* - 失败后继续执行,记录所有失败
TEST(ExpectTest, ContinuesOnFailure) {
    EXPECT_EQ(1, 2);  // 失败,但继续执行
    std::cout << "This will print" << std::endl;
    EXPECT_EQ(2, 2);  // 会执行并通过
    EXPECT_EQ(3, 4);  // 会执行并失败
}  // 测试结束时报告2个失败

何时使用 ASSERT 或 EXPECT:

  • 使用 ASSERT 检查前置条件
  • 使用 EXPECT 检查多个独立的条件

示例:

TEST(FileTest, ReadFile) {
    File* file = OpenFile("data.txt");
    
    // 如果文件打开失败,后续测试无意义
    ASSERT_NE(file, nullptr);

    EXPECT_EQ(file->GetSize(), 1024);
    EXPECT_EQ(file->GetType(), FileType::TEXT);
    EXPECT_TRUE(file->IsReadable());
    
    delete file;
}

布尔断言

Fatal assertionNonfatal assertionVerifies
ASSERT_TRUE(condition);EXPECT_TRUE(condition);condition is true
ASSERT_FALSE(condition);EXPECT_FALSE(condition);condition is false

示例:

TEST(BooleanAssertions, TrueFalse) {
    bool is_valid = true;
    bool is_empty = false;
    
    // 检查 true
    EXPECT_TRUE(is_valid);
    EXPECT_TRUE(10 > 5);
    EXPECT_TRUE(std::string("hello").length() > 0);
    
    // 检查 false
    EXPECT_FALSE(is_empty);
    EXPECT_FALSE(5 > 10);
    EXPECT_FALSE(std::string("").length() > 0);
    
    // 实际应用
    std::vector<int> vec = {1, 2, 3};
    EXPECT_FALSE(vec.empty());
    EXPECT_TRUE(std::find(vec.begin(), vec.end(), 2) != vec.end());
    
    // 条件表达式
    int x = 10;
    EXPECT_TRUE(x > 0 && x < 20);
    EXPECT_FALSE(x < 0 || x > 100);
}

基本值比较断言

Fatal assertionNonfatal assertionVerifies
ASSERT_EQ(expected, actual);EXPECT_EQ(expected, actual);expected == actual
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

相等性断言示例:

TEST(BasicAssertions, EqualityComparisons) {
    int a = 5, b = 5, c = 10;
    
    // 相等
    EXPECT_EQ(a, b);  // a == b
    ASSERT_EQ(2 + 2, 4);
    
    // 不相等
    EXPECT_NE(a, c);  // a != c
    ASSERT_NE(10, 20);
    
    // 对于指针比较
    int* p1 = &a;
    int* p2 = &a;
    int* p3 = &b;
    EXPECT_EQ(p1, p2);  // 比较指针值
    EXPECT_NE(p1, p3);
    
    // 对于自定义类型,需要定义 operator==
    class Point {
    public:
        int x, y;
        bool operator==(const Point& other) const {
            return x == other.x && y == other.y;
        }
    };
    
    Point pt1{1, 2}, pt2{1, 2}, pt3{3, 4};
    EXPECT_EQ(pt1, pt2);
    EXPECT_NE(pt1, pt3);
}

大小比较断言示例:

TEST(BasicAssertions, RelationalComparisons) {
    int small = 5, medium = 10, large = 15;
    
    // 小于
    EXPECT_LT(small, medium);   // small < medium
    ASSERT_LT(5, 10);
    
    // 小于等于
    EXPECT_LE(small, medium);   // small <= medium
    EXPECT_LE(10, 10);          // 相等也满足
    
    // 大于
    EXPECT_GT(large, medium);   // large > medium
    ASSERT_GT(100, 50);
    
    // 大于等于
    EXPECT_GE(large, medium);   // large >= medium
    EXPECT_GE(10, 10);          // 相等也满足
    
    // 组合使用验证范围
    int value = 50;
    EXPECT_GE(value, 0);
    EXPECT_LE(value, 100);
    // 或者
    EXPECT_TRUE(value >= 0 && value <= 100);
}

字符串断言

Fatal assertionNonfatal assertionVerifies
ASSERT_STREQ(str1, str2);EXPECT_STREQ(str1, str2);the two C strings have the same content
ASSERT_STRNE(str1, str2);EXPECT_STRNE(str1, str2);the two C strings have different content
ASSERT_STRCASEEQ(str1, str2);EXPECT_STRCASEEQ(str1, str2);the two C strings have the same content, ignoring case
ASSERT_STRCASENE(str1, str2);EXPECT_STRCASENE(str1, str2);the two C strings have different content, ignoring case

比较内容,而不是指针。

C 字符串断言示例:

TEST(StringAssertions, CStrings) {
    const char* str1 = "Hello";
    const char* str2 = "Hello";
    const char* str3 = "World";
    const char* str4 = "hello";
    const char* null_str = nullptr;
    
    // C字符串相等(比较内容,不是指针)
    EXPECT_STREQ(str1, str2);  // 内容相同
    EXPECT_STREQ("Test", "Test");
    
    // C字符串不相等
    EXPECT_STRNE(str1, str3);  // 内容不同
    EXPECT_STRNE("Hello", "World");
    
    // 忽略大小写比较
    EXPECT_STRCASEEQ(str1, str4);  // "Hello" == "hello" (忽略大小写)
    EXPECT_STRCASENE("Hello", "World");  // 忽略大小写仍不相等
    
    // 处理 nullptr
    EXPECT_STREQ(null_str, nullptr);  // 两个都是 nullptr
    // EXPECT_STREQ(str1, nullptr);  // 会失败
}

STREQ 和 STRNE 同时支持 char* 和 wchar_t* 类型,STRCASEEQ 和 STRCASENE 只接收 char* 类型。

C++ string 断言示例:

TEST(StringAssertions, CppStrings) {
    std::string str1 = "Hello";
    std::string str2 = "Hello";
    std::string str3 = "World";
    std::string empty = "";
    
    // 使用 EQ/NE 比较 std::string
    EXPECT_EQ(str1, str2);
    EXPECT_NE(str1, str3);
    EXPECT_EQ(empty, "");
    
    // 子字符串检查
    EXPECT_TRUE(str1.find("ell") != std::string::npos);
    EXPECT_TRUE(str1.starts_with("Hel"));  // C++20
    EXPECT_TRUE(str1.ends_with("lo"));     // C++20
    
    // 正则表达式匹配(使用 matcher)
    using ::testing::MatchesRegex;
    EXPECT_THAT(str1, MatchesRegex("H.*o"));
}

当使用 Bazel 和 Abseil 构建时,GoogleTest 使用 RE2 语法。否则,对于 POSIX 系统(Linux、Cygwin、Mac), GoogleTest 将使用 POSIX 扩展正则表达式语法。

下面是 GoogleTest 支持的正则表达式语法:

ExpressionMeaning
cmatches any literal character c
\dmatches any decimal digit
\Dmatches any character that’s not a decimal digit
\fmatches \f
\nmatches \n
\rmatches \r
\smatches any ASCII whitespace, including \n
\Smatches any character that’s not a whitespace
\tmatches \t
\vmatches \v
\wmatches any letter, _, or decimal digit
\Wmatches any character that \w doesn’t match
\cmatches any literal character c, which must be a punctuation
.matches any single character except \n
A?matches 0 or 1 occurrences of A
A*matches 0 or many occurrences of A
A+matches 1 or many occurrences of A
^matches the beginning of a string (not that of each line)
$matches the end of a string (not that of each line)
xymatches x followed by y

浮点数断言

Fatal assertionNonfatal assertionVerifies
ASSERT_FLOAT_EQ(expected, actual);EXPECT_FLOAT_EQ(expected, actual);the two float values are almost equal
ASSERT_DOUBLE_EQ(expected, actual);EXPECT_DOUBLE_EQ(expected, actual);the two double values are almost equal
ASSERT_NEAR(val1, val2, abs_error);EXPECT_NEAR(val1, val2, abs_error);the difference between val1 and val2 doesn’t exceed the given absolute error

基本浮点数比较示例:

TEST(FloatingPointAssertions, BasicComparisons) {
    float f1 = 1.0f / 3.0f;
    float f2 = 0.333333f;
    
    double d1 = 1.0 / 3.0;
    double d2 = 0.333333333333;
    
    // float 比较(使用 ULP - Units in the Last Place)
    EXPECT_FLOAT_EQ(f1, f2);  // 允许小误差
    EXPECT_FLOAT_EQ(1.0f, 1.0f);
    
    // double 比较
    EXPECT_DOUBLE_EQ(d1, d2);  // 允许小误差
    EXPECT_DOUBLE_EQ(1.0, 1.0);
    
    // 指定绝对误差范围
    EXPECT_NEAR(f1, f2, 0.0001);  // |f1 - f2| < 0.0001
    EXPECT_NEAR(d1, d2, 0.000001);
    
    // 实际计算示例
    float result = std::sqrt(2.0f) * std::sqrt(2.0f);
    EXPECT_NEAR(result, 2.0f, 0.00001);  // 不能用 EXPECT_EQ
}

特殊浮点值示例:

TEST(FloatingPointAssertions, SpecialValues) {
    double inf = std::numeric_limits<double>::infinity();
    double nan = std::numeric_limits<double>::quiet_NaN();
    
    // 无穷大
    EXPECT_DOUBLE_EQ(inf, inf);
    EXPECT_TRUE(std::isinf(inf));
    
    // NaN 的特殊处理
    // EXPECT_DOUBLE_EQ(nan, nan);  // 会失败!NaN != NaN
    EXPECT_TRUE(std::isnan(nan));
    
    // 检查是否为有限值
    EXPECT_TRUE(std::isfinite(1.0));
    EXPECT_FALSE(std::isfinite(inf));
    EXPECT_FALSE(std::isfinite(nan));
}

显示返回成功或失败

直接返回成功:SUCCEED();

返回失败:

Fatal assertionNonfatal assertion
FAIL();ADD_FAILURE();

示例:

TEST(ExplicitTest, Demo)
{
	// None Fatal Asserton,继续往下执行
    ADD_FAILURE() << "Sorry";
    // FAIL(); // Fatal Assertion,不往下执行该案例
    SUCCEED();
}

异常断言

Fatal assertionNonfatal assertionVerifies
ASSERT_THROW(statement, exception_type);EXPECT_THROW(statement, exception_type);statement throws an exception of the given type
ASSERT_ANY_THROW(statement);EXPECT_ANY_THROW(statement);statement throws an exception of any type
ASSERT_NO_THROW(statement);EXPECT_NO_THROW(statement);statement doesn’t throw any exception

基本异常断言示例:

class Calculator {
public:
    double divide(double a, double b) {
        if (b == 0) {
            throw std::invalid_argument("Division by zero");
        }
        return a / b;
    }
    
    int factorial(int n) {
        if (n < 0) {
            throw std::domain_error("Negative input");
        }
        if (n > 20) {
            throw std::overflow_error("Input too large");
        }
        // 计算阶乘...
        return 1;  // 简化
    }
};

TEST(ExceptionAssertions, BasicExceptions) {
    Calculator calc;
    
    // 期望抛出特定类型的异常
    EXPECT_THROW(calc.divide(10, 0), std::invalid_argument);
    EXPECT_THROW(calc.factorial(-5), std::domain_error);
    
    // 期望抛出任何异常
    EXPECT_ANY_THROW(calc.divide(10, 0));
    EXPECT_ANY_THROW(calc.factorial(-1));
    
    // 期望不抛出异常
    EXPECT_NO_THROW(calc.divide(10, 2));
    EXPECT_NO_THROW(calc.factorial(5));
}

进阶示例 - 验证异常信息:

TEST(ExceptionAssertions, ExceptionMessage) {
    Calculator calc;
    
    // 使用 try-catch 验证异常消息
    try {
        calc.divide(10, 0);
        FAIL() << "Expected exception was not thrown";
    } catch (const std::invalid_argument& e) {
        EXPECT_STREQ(e.what(), "Division by zero");
    } catch (...) {
        FAIL() << "Wrong exception type";
    }
    
    // 使用 lambda 和断言宏
    auto throw_with_message = []() {
        throw std::runtime_error("Custom error message");
    };
    
    EXPECT_THROW({
        try {
            throw_with_message();
        } catch (const std::runtime_error& e) {
            EXPECT_STREQ(e.what(), "Custom error message");
            throw;  // 重新抛出以满足 EXPECT_THROW
        }
    }, std::runtime_error);
}

谓词断言

Fatal assertionNonfatal assertionVerifies
ASSERT_PRED1(pred1, val1);EXPECT_PRED1(pred1, val1);pred1(val1) returns true
ASSERT_PRED2(pred2, val1, val2);EXPECT_PRED2(pred2, val1, val2);pred2(val1, val2) returns true
………

GoogleTest 只提供 <= 5 个参数的谓词断言。

示例:

// 自定义谓词函数
bool IsEven(int n) {
    return n % 2 == 0;
}

bool IsInRange(int value, int min, int max) {
    return value >= min && value <= max;
}

TEST(PredicateAssertions, UnaryPredicates) {
    // 一元谓词
    EXPECT_PRED1(IsEven, 4);
    EXPECT_FALSE(IsEven(3));
    
    // 使用 lambda
    auto is_positive = [](int x) { return x > 0; };
    EXPECT_PRED1(is_positive, 10);
}

TEST(PredicateAssertions, BinaryPredicates) {
    // 二元谓词
    auto greater_than = [](int a, int b) { return a > b; };
    EXPECT_PRED2(greater_than, 10, 5);
    
    // 三元谓词
    EXPECT_PRED3(IsInRange, 200, 0, 100);
}

当失败时,返回错误信息:

error: IsInRange(value, min, max) evaluates to false, where
value evaluates to 200
min evaluates to 0
max evaluates to 100

如果对这样的输出不满意的话,还可以自定义输出格式,通过如下断言:

Fatal assertionNonfatal assertionVerifies
ASSERT_PRED_FORMAT1(pred_format1, val1);EXPECT_PRED_FORMAT1(pred_format1, val1);pred_format1(val1) is successful
ASSERT_PRED_FORMAT2(pred_format2, val1, val2);EXPECT_PRED_FORMAT2(pred_format2, val1, val2);pred_format2(val1, val2) is successful
………

示例:

// 自定义格式化函数
testing::AssertionResult AssertSumEquals(
    const char* a_expr,
    const char* b_expr,
    const char* sum_expr,
    int a,
    int b,
    int sum) {
    if (a + b == sum) {
        return testing::AssertionSuccess();
    }
    
    return testing::AssertionFailure()
        << a_expr << " + " << b_expr << " (" << a << " + " << b
        << ") does not equal " << sum_expr << " (" << sum << ")";
}

TEST(FormattedPredicates, CustomFormat) {
    EXPECT_PRED_FORMAT3(AssertSumEquals, 2, 3, 5);
    // EXPECT_PRED_FORMAT3(AssertSumEquals, 2, 3, 6);  
    // 失败消息: "2 + 3 (2 + 3) does not equal 6 (6)"
}

死亡断言

DEATH

Fatal assertionNonfatal assertionVerifies
ASSERT_DEATH(statement, regex);EXPECT_DEATH(statement, regex);断言给定的语句会以某种原因导致进程终止,并且终止时输出的错误信息(通常是 stderr)匹配给定的正则表达式

工作原理:

  1. GoogleTest 会 fork 出一个子进程。
  2. 在该子进程中执行 statement。
  3. 如果子进程如预期般终止(例如,由于信号或 _exit),并且其 stderr 输出匹配 regex,则断言成功。
  4. 如果子进程正常执行完毕没有终止,或者终止信息不匹配 regex,则断言失败。

示例:

void FunctionThatAborts(int x) {
  if (x < 0) {
    abort(); // 终止进程,通常会产生 "Aborted" 之类的输出
  }
}

void FunctionWithAssert(int x) {
  assert(x >= 0); // 如果 NDEBUG 未定义,assert 失败会终止程序
}

TEST(DeathTest, ExpectDeathExample) {
  // 测试 abort()
  EXPECT_DEATH(FunctionThatAborts(-1), "Aborted|abort|Assertion");

  // 测试 assert() 失败 (需确保在 Debug 模式下编译,未定义 NDEBUG)
#ifndef NDEBUG
  EXPECT_DEATH(FunctionWithAssert(-1), "assertion.*failed");
#endif

  // 测试一个会导致除零错误的语句
  EXPECT_DEATH({
      int a = 1 / 0; // 通常会产生 "Floating point exception" 或类似信息
  }, "Floating|division|exception");
}

DEBUG_DEATH

Fatal assertionNonfatal assertionVerifies
ASSERT_DEBUG_DEATH(statement, regex);EXPECT_DEBUG_DEATH(statement, regex);条件性的死亡测试宏

EXPECT_DEBUG_DEATH 的行为会根据编译模式(Debug 或 Release)而改变:

  • 在 Debug 模式(未定义 NDEBUG)下:行为与 EXPECT_DEATH 完全一样,会执行死亡测试。

  • 在 Release 模式(定义了 NDEBUG)下:不会执行死亡测试,而是直接跳过。语句根本不会运行。

这主要为了解决一个常见问题:assert() 宏在 Release 模式下的行为。

我们知道:

  • 在 Debug 模式:assert(condition) 会在条件为假时终止程序。

  • 在 Release 模式(定义了 NDEBUG):assert() 宏会被预处理器完全移除,代码根本不会执行。

示例:

// 一个使用 assert 进行参数检查的函数
void ProcessValue(int* ptr, int value) {
  assert(ptr != nullptr);    // Debug 模式检查,Release 模式无此检查
  assert(value >= 0 && value <= 100); // 值域检查
  
  *ptr = value * 2;
}

TEST(DebugDeathTest, TestAssertBehavior) {
  int result;
  
  // 测试空指针断言 - 只在 Debug 模式下进行
  EXPECT_DEBUG_DEATH(ProcessValue(nullptr, 42), "assertion.*failed");
  
  // 测试越界值断言 - 只在 Debug 模式下进行  
  EXPECT_DEBUG_DEATH(ProcessValue(&result, -1), "assertion.*failed");
  EXPECT_DEBUG_DEATH(ProcessValue(&result, 101), "assertion.*failed");
  
  // 正常的测试用例 - 在所有模式下都运行
  ProcessValue(&result, 50);
  EXPECT_EQ(result, 100);
}

// 测试 abort() - 这个在任何模式下都会终止,所以用 EXPECT_DEATH
void FunctionThatAborts() {
  abort();
}

TEST(DebugDeathTest, TestAbort) {
  // abort() 在任何模式下都有效,所以用普通的 EXPECT_DEATH
  EXPECT_DEATH(FunctionThatAborts(), "Aborted|abort");
}

EXIT

Fatal assertionNonfatal assertionVerifies
ASSERT_EXIT(statement, predicate, regex);EXPECT_EXIT(statement, predicate, regex);断言给定的语句会以某种原因导致进程终止,并且终止时退出状态码匹配 predicate,输出的错误信息(通常是 stderr)匹配 regex

参数解释:

  • statement:要测试的语句。

  • predicate:一个函数或可调用对象,用于检查进程的退出状态。它接受一个 int 参数(退出状态码),并返回 bool(true 表示匹配期望)。

  • regex:与 EXPECT_DEATH 一样,用于匹配 stderr 输出的正则表达式。

GoogleTest 提供了一些方便的包装函数作为 predicate:

  • ::testing::ExitedWithCode(exit_code): 进程正常退出,并且退出码等于 exit_code。
    例如: exit(3) 会被 ExitedWithCode(3) 匹配。
  • ::testing::KilledBySignal(signal_number): 进程被指定的信号杀死。
    例如: abort() 通常会发送 SIGABRT 信号,可被 KilledBySignal(SIGABRT) 匹配。

示例:

void ExitWithFailure() {
  std::cerr << "Critical error occurred!" << std::endl;
  exit(EXIT_FAILURE); // 通常 EXIT_FAILURE 是 1
}

void AbortProgram() {
  abort(); // 发送 SIGABRT 信号终止自己
}

TEST(DeathTest, ExpectExitExample) {
  // 测试程序是否以 EXIT_FAILURE (通常是1) 退出,并且输出特定信息
  EXPECT_EXIT(ExitWithFailure(),
              ::testing::ExitedWithCode(EXIT_FAILURE),
              "Critical error");

  // 测试程序是否因为 SIGABRT 信号而终止
  // abort() 不会产生退出码,而是被信号杀死,所以要用 KilledBySignal
  EXPECT_EXIT(AbortProgram(),
              ::testing::KilledBySignal(SIGABRT),
              ""); // 这里不关心输出,所以用空字符串匹配

  // 你也可以使用自定义的谓词函数
  EXPECT_EXIT(exit(42),
              [](int exit_status) { return exit_status == 42; },
              "");
}

Windows HRESULT 断言

GoogleTest 专门为 Windows COM 编程设计的自定义断言宏。

这个宏用于验证 HRESULT 类型的值是否表示成功。在 COM 编程中,HRESULT 是一个 32 位的值,用于表示操作的成功或失败状态。

Fatal assertionNonfatal assertionVerifies
ASSERT_HRESULT_SUCCEEDED(expression);EXPECT_HRESULT_SUCCEEDED(expression);expression is a success HRESULT
ASSERT_HRESULT_FAILED(expression);EXPECT_HRESULT_FAILED(expression);expression is a failure HRESULT

示例:

#include <gtest/gtest.h>
#include <windows.h>
#include <comdef.h> // 用于 _com_error

class COMTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 初始化 COM(如果需要)
        CoInitialize(nullptr);
    }
    
    void TearDown() override {
        CoUninitialize();
    }
};

TEST_F(COMTest, TestCOMCreation) {
    IUnknown* pUnknown = nullptr;
    
    // 测试成功的 COM 调用
    HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
                                 nullptr, 
                                 CLSCTX_INPROC_SERVER, 
                                 IID_PPV_ARGS(&pUnknown));
    
    ASSERT_HRESULT_SUCCEEDED(hr);
    ASSERT_NE(pUnknown, nullptr);
    
    pUnknown->Release();
}

TEST_F(COMTest, TestCOMFailure) {
    IUnknown* pUnknown = nullptr;
    
    // 测试一个应该失败的 COM 调用(使用无效的 CLSID)
    HRESULT hr = CoCreateInstance(CLSID_NULL, // 无效的 CLSID
                                 nullptr, 
                                 CLSCTX_INPROC_SERVER, 
                                 IID_PPV_ARGS(&pUnknown));
    
    // 这个断言应该会失败,并提供详细的错误信息
    ASSERT_HRESULT_SUCCEEDED(hr); // 这会显示具体的 HRESULT 错误值
}

这个宏是 Windows 平台特有的,需要包含 Windows 头文件和链接相应的库。

Matcher 断言(高级)

GoogleTest 中最强大、最灵活的断言机制。EXPECT_THAT 配合 Matcher 是 GoogleTest 的"瑞士军刀"。

Matcher 是一个描述期望值的谓词对象,它知道如何检查一个值是否满足特定条件,并能生成友好的错误消息。

Fatal assertionNonfatal assertionVerifies
ASSERT_THAT(actual_value, matcher);EXPECT_THAT(actual_value, matcher);断言 actual_value 满足 matcher 所描述的条件

与传统断言相比,Matcher 断言提供了:

  1. 更丰富的比较能力

  2. 更清晰的错误消息

  3. 可组合的复杂条件

  4. 更好的可读性

通用比较 Matcher

EXPECT_THAT(value, Eq(42));      // 等于 ==
EXPECT_THAT(value, Ne(0));       // 不等于 !=  
EXPECT_THAT(value, Gt(40));      // 大于 >
EXPECT_THAT(value, Ge(42));      // 大于等于 >=
EXPECT_THAT(value, Lt(50));      // 小于 <
EXPECT_THAT(value, Le(42));      // 小于等于 <=

浮点数比较 Matcher

double result = CalculateSomething();
EXPECT_THAT(result, DoubleEq(3.14));     // 精确相等
EXPECT_THAT(result, NanSensitiveDoubleEq(3.14)); // 处理NaN
EXPECT_THAT(result, DoubleNear(3.14, 0.01)); // 近似相等,误差0.01

字符串 Matcher

std::string str = "Hello GoogleTest";
EXPECT_THAT(str, StartsWith("Hello"));
EXPECT_THAT(str, EndsWith("GoogleTest"));
EXPECT_THAT(str, Contains("Google"));
EXPECT_THAT(str, HasSubstr("Test"));
EXPECT_THAT(str, MatchesRegex("Hello.*Test")); // 正则匹配

容器 Matcher

std::vector<int> vec = {1, 2, 3, 4, 5};
std::map<std::string, int> map = {{"a", 1}, {"b", 2}};

EXPECT_THAT(vec, Contains(3));                   // 包含元素
EXPECT_THAT(vec, ElementsAre(1, 2, 3, 4, 5));   // 精确序列匹配
EXPECT_THAT(vec, UnorderedElementsAre(5, 4, 3, 2, 1)); // 无序包含
EXPECT_THAT(vec, SizeIs(5));                     // 大小检查

EXPECT_THAT(map, Contains(Key("a")));            // 包含键
EXPECT_THAT(map, Contains(Pair("b", 2)));        // 包含键值对

指针和引用 Matcher

int x = 42;
int* ptr = &x;
EXPECT_THAT(ptr, NotNull());                    // 非空指针
EXPECT_THAT(ptr, Pointee(Eq(42)));              // 指针指向的值
EXPECT_THAT(x, Ref(x));                         // 是同一对象的引用

组合 Matcher

using ::testing::AllOf;  // 所有条件都满足(AND)
using ::testing::AnyOf;  // 任一条件满足(OR)
using ::testing::Not;    // 条件不满足(NOT)

int value = 42;
EXPECT_THAT(value, AllOf(Gt(40), Lt(50)));        // 40 < value < 50
EXPECT_THAT(value, AnyOf(Eq(40), Eq(42), Eq(44))); // value是40,42或44
EXPECT_THAT(value, Not(Lt(40)));                  // value不小于40
MSTAR数据集下载地址及处理方法 首先感谢博主冯子材提供下载的百度网盘地址。 在这里为了防止侵权,特此鸣谢,并给出其博客地址。 地址中有MSTAR百度网盘下载地址和需要使用的数据介绍,其中百度网盘中有数据转换工具 https://blog.youkuaiyun.com/taifengzikai/article/details/80600355 工具使用 因为下载得到的数据是二进制文件,需要使用官方提供的工具进行转换,可将其转换为jpeg。 有... 阅读详情

相关推荐

mtk-drm commit送显流程(二):内核态atomic_commit实现解析

本文深入解析了mtk-drm框架中atomic_commit机制的内核态实现流程,详细介绍了从用户态触发到硬件提交的完整调用链,包括状态检查、硬件提交等关键阶段。特别分析了MTK平台在动态刷新率、内存带宽优化等方面的特有实现策略,为开发者提供了调试技巧和常见问题解决方案。

weixin_30839881的博客 1305

GoogleTest之断言

gtest中assert的头文件: gtest/gtest.hEXPECT_和ASSERT_两种形式,EXPECT_产生非致命错误,ASSERT_产生致命错误并中断当前函数;所有断言宏支持使用重载

u010378559的博客 6145

现场总线课程设计-基于modbus协议使用QT实现主从站控制通信

【平台:QT】 【协议:modbus(注:由于要求,需要自己来实现modbus库,而非直接调用已有的库)】 【由于复制粘贴,时间原因可能格式有误,如需要具体工程文件以及报告文件请私信博主】 1、 大作业任务: (1)使用附件中工具软件体验MODBUS主从站数据传输过程(可在主从站模拟工具里面观察各功能码对应数据帧内容并对其进行分析) (2)使用串口调试助手,手工发出MODBUS主、从站该发出的数据,并观察对方发出的数据 (3)实现MODBUS主、从站功能,描述实现过程(语言不限于使用VC

weixin_44469597的博客 4065

跟我学c++中级篇工具应用——gtest的断言

一、gtest的断言 断言,其实就是一种“逻辑判断”。它从数学理论中导出来的,在数学中的英文描述是“A narrative communication which by virtue of its meaning is true or false. In a narrower sense, the term assertion in mathematical logic is understood to be a closed formula in a logico-mathematical languag

fpcc的专栏 3053

F280049C_HRPWM_死区时间高精度控制与MEP技术实战解析

本文深入解析了F280049C的HRPWM模块及其基于MEP技术的死区时间高精度控制。通过实测数据与TI官方代码对比,详细阐述了DBREDHR和DBFEDHR寄存器的配置技巧、精度优化方法及常见问题调试,为电源管理和电机控制应用提供了实用的实战指南。

yolo5detector的博客 217

MODBUS通讯不求人:手把手教你用三菱FX2N控制士林变频器

本文详细介绍了如何使用三菱FX2N PLC通过MODBUS协议控制士林变频器,涵盖硬件连接、参数配置、程序设计及通讯优化等关键步骤。特别针对没有内置MODBUS函数块的老款PLC,提供了CRC校验和稳定数据交换的实用解决方案,帮助工程师快速实现工业自动化设备的高效通讯。

v4w5x6的博客 226

assert断言 - googletest(二)

单元测试的基本理论

生活需要深度 1328

【脚本篇】---spyglass lint脚本

【代码】【脚本篇】---spyglass lint脚本。

冬瓜 6355

GoogleTest使用教程

GoogleTest是由Google开发的一个C++测试框架,支持Linux、Windows和macOS操作系统,使用Bazel或CMake构建工具。

zzy979481894的博客 1万+

Mybatis Provider注解实现批量插入

需求 借助mybatis 的provider实现一个比较通用的,批量插入数据接口。 Mapper接口 第一参数为需要批量插入的数据,第二个参数为对应实体类的class public interface BaseDao<T> { @InsertProvider(type = BaseProvider.class, method = "batchInsert") int batchInsert(@Param("lists") List<T&gt

小楼夜听雨的博客 2417

图像处理入门007:图像处理中的数学基础:线性代数与卷积

一种:把 OpenCV 当黑盒,调用,效果不对就乱调参数;另一种:理解每个像素是怎么被周围邻域"加权平均"的,理解核翻转、边界填充、stride 的含义。前者能干活,后者能解难题。一旦遇到自定义核(比如 ISP 上的锐化)、深度学习反向传播、医学图像重建,你就必须把卷积、相关、矩阵乘法这些基本功捡回来。线性代数三件套:向量点积、矩阵乘法、线性变换;2D 卷积的数学定义:核翻转、滑动窗口、边界填充。并手写一个,验证它与和的结果完全一致(误差 < 1e-9)。f∗gn∑m−∞∞f。

专注:太空算力、AI infra、异构调度、大模型成本工程 386

GoogleTest断言详解:30种断言方法让你彻底掌握测试验证

GoogleTest是C++领域最流行的单元测试框架之一,其强大的断言系统是测试验证的核心。本文将为你详细解析GoogleTest的30种断言方法,帮助你彻底掌握测试验证技巧。😊 ## GoogleTest断言概述 GoogleTest断言是测试验证的基础工具,位于[googletest/include/gtest/gtest.h](https://link.gitcode.com/i/01

gitblog_00022的博客 842

【20】方案管理器

方案管理器是Excel中一个非常强大且灵活的工具,适合用于多情景分析和比较。在复杂的决策过程中,它可以帮助用户快速管理和评估不同变量组合下的结果,从而优化决策过程。

学习,输出==》再学习再输出 1585

GoogleTest 使用指南 |自定义断言

GoogleTest 使用指南 |自定义断言

ProgramNovice的博客 83

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

gperftools 测试基础设施中的 GoogleTest 断言宏全解析:EXPECT_ 与 ASSERT_ 使用指南

> 本文以 gperftools 仓库 vendored 的 GoogleTest 官方参考文档 [vendor/googletest/docs/reference/assertions.md](https://link.gitcode.com/i/36eb2474ba686647e300f9e36b2b9af4) 为骨架,系统梳理 GoogleTest 全部断言宏的分类、语义与使用边界,并结合仓

gitblog_00930的博客 792

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

GoogleTest--断言

介绍GoogleTest中的常见断言的种类

king110108的专栏 1258

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

GoogleTest断言机制全面解析

GoogleTest断言机制全面解析 【免费下载链接】googletest 由 Google 开发的一款用于 C++ 的单元测试和模拟(mocking)框架 项目地址: https://gitcode.com/GitHub_Tre...

gitblog_00751的博客 434

GoogleTest测试框架介绍(一)

本系列文章主要介绍GoogleTest(也称“GTest”)测试框架的相关知识,同时通过一些示例程序介绍GoogleTest测试框架的使用方法。本文为系列文章的第一篇,主要介绍GoogleTest测试框架的相关知识。

liitdar的博客 3万+

BusTub 测试实战:GoogleTest 断言宏(Assertions)完整参考与源码用例解析

本文以 GoogleTest 官方断言参考([third_party/googletest/docs/reference/assertions.md](https://link.gitcode.com/i/5e03d57cab349203a5f54217871a7c53))为骨架,系统讲解 `EXPECT_*` 与 `ASSERT_*` 全系断言宏的语义、适用场景与易错点,并穿插 BusTub 仓

gitblog_00405的博客 1030

致命断言终结者:GoogleTest ASSERT系列让错误无所遁形

你是否曾因单元测试中隐藏的逻辑错误浪费数小时调试?是否遇到过测试明明失败却继续执行导致的连锁错误?GoogleTest(简称GTest)的ASSERT系列断言(Assertion,断言)正是解决这些痛点的利器。本文将带你掌握ASSERT断言的核心机制、实战用法和最佳实践,让你的C++测试代码更健壮、调试更高效。 ## ASSERT断言:测试失败的"紧急刹车" 在单元测试(Unit Testin...

gitblog_01092的博客 901

GoogleTest 使用指南 | 简介

GoogleTest 使用指南 | 简介

ProgramNovice的博客 1090

GoogleTest测试框架使用详解(从零到精通,最详细版)

GoogleTest是一款由Google开发的C++测试框架,具有快速、简洁、可靠、跨平台等优点,可以帮助C++开发人员更好的测试代码。本文将根据谷歌官方资料,全面介绍GoogleTest测试框架的使用,并在vs2022上进行验证。本文旨在从零开始学习GoogleTest测试框架,适合没有GoogleTest相关知识的学习者和想全面了解该框架使用的学习者。GoogleTest的结构较为简单,跟着本文进行学习定会在短时间内掌握其使用!

不知名的代码小白 1万+

(笔记)googletest在C语言项目中的使用指南

googletest在C语言项目中的使用指南

weixin_44374981的博客 5037

终极指南:掌握GoogleTest EXPECT系列断言,让C++单元测试更高效

在C++单元测试领域,GoogleTest(简称GTest)是由Google开发的一款功能强大的单元测试和模拟框架。其中,**EXPECT系列断言**作为非致命失败检测的核心工具,能够在测试过程中发现问题的同时继续执行后续测试用例,极大提升测试效率和问题定位能力。本文将深入解析EXPECT系列断言的使用方法、核心优势及实战技巧,帮助开发者构建更健壮的测试体系。 ## 🧩 什么是EXPECT系列

gitblog_00609的博客 1165

GoogleTest自定义断言宏教程:像ASSERT_EQ一样创建你自己的C++测试宏

GoogleTest(Google Testing and Mocking Framework)是 Google 开源的 C++ 测试框架,内置了 ASSERT_EQ、EXPECT_TRUE 等常用断言宏。当内置断言无法满足业务场景时,你可以亲手创建自己的 C++ 测试宏。本文将用 3 种由易到难的方法,带你掌握 GoogleTest 自定义断言宏的完整写法,让测试输出更清晰、更贴近你的项目语言。

gitblog_00930的博客 648

深入解析 googletest FAQ:命名规则、死亡测试与断言宏陷阱实战指南

googletest(GoogleTest)是业界广泛使用的 C++ 单元测试框架,其[官方 FAQ 文档](https://link.gitcode.com/i/2414201c9788be9e8430835b4b0949bc)记录了开发者在使用过程中最容易踩中的二十余个"坑":从 `TEST`/`TEST_F` 命名下划线规则、NULL 指针断言、typed/value-parameteriz

gitblog_00612的博客 447
上一篇: GoogleTest 使用指南 | 简介
下一篇: GoogleTest 使用指南 | 安装 GoogleTest
UestcXiye
博客等级 码龄8年 9029粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值