[Google Test]- Google Test Ubuntu 完整验证指南

Google Test Ubuntu 完整验证指南

一、环境安装

1.1 安装依赖

sudo apt-get update

sudo apt-get install -y build-essential cmake libgtest-dev git

1.2 编译 gtest 库(重要!)

libgtest-dev 只安装源码,需要手动编译:

cd /usr/src/gtest

sudo cmake CMakeLists.txt

sudo make

sudo cp *.a /usr/lib

或者使用 CMake FetchContent(推荐,无需系统安装)

二、项目结构

gtest_template_test/

├── CMakeLists.txt

├── include/

│ └── calculator.hpp # 被测试的模板类

├── src/

│ └── main.cpp # 可选的主程序

└── tests/

└── test_calculator.cpp # 测试代码

三、被测试的模板类(非虚接口)

复制代码

include/calculator.hpp

ifndef CALCULATOR_HPP

define CALCULATOR_HPP

include

include

// 模板类 - 非虚接口(编译时多态)

template

class Calculator {

public:

// 非虚成员函数

T add(T a, T b) const {

return a + b;

}

复制代码
T subtract(T a, T b) const {
    return a - b;
}

T multiply(T a, T b) const {
    return a * b;
}

T divide(T a, T b) const {
    if (b == T{}) {
        throw std::invalid_argument("Division by zero");
    }
    return a / b;
}

// 模板成员函数
template
T accumulate(const U* begin, const U* end, T init) const {
    T result = init;
    for (const U* ptr = begin; ptr != end; ++ptr) {
        result = add(result, static_cast(*ptr));
    }
    return result;
}

};

// 模板特化示例

template

class Calculator {

public:

const char* add(const char* a, const char* b) const {

return "string_concat_not_supported";

}

};

endif // CALCULATOR_HPP

四、测试代码

tests/test_calculator.cpp

include

include "calculator.hpp"

include

include

include

// ============================================

// 测试夹具(Test Fixture)- 用于模板测试

// ============================================

template

class CalculatorTest : public ::testing::Test {

protected:

Calculator calc;

复制代码
void SetUp() override {
    // 每个测试前执行
}

void TearDown() override {
    // 每个测试后执行
}

};

// 定义测试类型列表

using TestTypes = ::testing::Types;

TYPED_TEST_SUITE(CalculatorTest, TestTypes);

// ============================================

// 类型化测试(Typed Tests)

// ============================================

TYPED_TEST(CalculatorTest, AddTest) {

TypeParam result = this->calc.add(TypeParam{2}, TypeParam{3});

EXPECT_EQ(TypeParam{5}, result);

}

TYPED_TEST(CalculatorTest, SubtractTest) {

TypeParam result = this->calc.subtract(TypeParam{10}, TypeParam{4});

EXPECT_EQ(TypeParam{6}, result);

}

TYPED_TEST(CalculatorTest, MultiplyTest) {

TypeParam result = this->calc.multiply(TypeParam{3}, TypeParam{4});

EXPECT_EQ(TypeParam{12}, result);

}

TYPED_TEST(CalculatorTest, DivideTest) {

TypeParam result = this->calc.divide(TypeParam{20}, TypeParam{4});

EXPECT_EQ(TypeParam{5}, result);

}

TYPED_TEST(CalculatorTest, DivideByZeroThrows) {

EXPECT_THROW(this->calc.divide(TypeParam{10}, TypeParam{0}),

std::invalid_argument);

}

// ============================================

// 非模板类的普通测试

// ============================================

TEST(CalculatorTest, AccumulateFunction) {

Calculator calc;

std::vector numbers = {1, 2, 3, 4, 5};

int result = calc.accumulate(numbers.data(),

numbers.data() + numbers.size(),

0);

EXPECT_EQ(15, result);

}

// ============================================

// 参数化测试(Parameterized Tests)

// ============================================

class ParameterizedCalcTest : public ::testing::TestWithParam> {

protected:

Calculator calc;

};

TEST_P(ParameterizedCalcTest, AddParameterized) {

auto a, b, expected = GetParam();

EXPECT_EQ(expected, calc.add(a, b));

}

INSTANTIATE_TEST_SUITE_P(

AdditionCases,

ParameterizedCalcTest,

::testing::Values(

std::make_tuple(1, 2, 3),

std::make_tuple(10, 20, 30),

std::make_tuple(-5, 5, 0),

std::make_tuple(100, 200, 300)

)

);

// ============================================

// 浮点数比较测试

// ============================================

TEST(FloatCalculatorTest, FloatingPointComparison) {

Calculator calc;

double result = calc.divide(1.0, 3.0);

EXPECT_DOUBLE_EQ(0.3333333333333333, result);

EXPECT_NEAR(0.3333, result, 0.0001); // 允许误差

}

// ============================================

// 死亡测试(Death Test)- 验证程序崩溃

// ============================================

TEST(DeathTest, DivisionByZeroCrash) {

// 注意:死亡测试需要特殊编译标志

Calculator calc;

// EXPECT_DEATH(calc.divide(10, 0), ".*"); // 需要启用

}

// ============================================

// Main 函数

// ============================================

int main(int argc, char **argv) {

::testing::InitGoogleTest(&argc, argv);

return RUN_ALL_TESTS();

}

五、CMakeLists.txt 配置

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(GTestTemplateTest LANGUAGES CXX)

C++ 标准

set(CMAKE_CXX_STANDARD 17)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

方法1: 使用系统安装的 gtest

find_package(GTest REQUIRED)

include_directories({GTEST_INCLUDE_DIRS})

方法2: 使用 FetchContent(推荐,无需系统安装)

include(FetchContent)

FetchContent_Declare(

googletest

GIT_REPOSITORY https://github.com/google/googletest.git

GIT_TAG v1.14.0

)

FetchContent_MakeAvailable(googletest)

包含目录

include_directories({CMAKE_SOURCE_DIR}/include)

测试可执行文件

add_executable(run_tests tests/test_calculator.cpp)

链接 gtest

target_link_libraries(run_tests

GTest::gtest

GTest::gtest_main

pthread

)

启用测试

enable_testing()

add_test(NAME TemplateTests COMMAND run_tests)

编译选项(启用死亡测试需要)

target_compile_definitions(run_tests PRIVATE GTEST_HAS_DEATH_TEST=1)

复制代码

六、编译与运行

6.1 创建构建目录并编译

mkdir build && cd build

cmake ...

make -j$(nproc)

6.2 运行测试

运行所有测试

./run_tests

运行特定测试套件

./run_tests --gtest_filter="CalculatorTest.*"

运行类型化测试

./run_tests --gtest_filter=TypedTest"

运行参数化测试

./run_tests --gtest_filter=Parameterized"

列出所有测试

./run_tests --gtest_list_tests

输出 XML 报告

./run_tests --gtest_output=xml:test_report.xml

6.3 预期输出示例

\[\] Running 15 tests from 4 test suites.
---------- Global test environment set-up.
---------- 5 tests from CalculatorTest/0, where TypeParam = int
RUN CalculatorTest/0.AddTest
OK CalculatorTest/0.AddTest (0 ms)
RUN CalculatorTest/0.SubtractTest
OK CalculatorTest/0.SubtractTest (0 ms)
...
---------- 4 tests from AdditionCases/ParameterizedCalcTest
RUN AdditionCases/ParameterizedCalcTest.AddParameterized/0
OK AdditionCases/ParameterizedCalcTest.AddParameterized/0 (0 ms)
...
\[\] 15 tests from 4 test suites ran. (2 ms total)

PASSED 15 tests.

七、关键要点总结

特性 说明

非虚模板接口 使用 TYPED_TEST_SUITE 进行类型化测试

测试夹具 模板类 CalculatorTest 继承 ::testing::Test

参数化测试 TestWithParam + INSTANTIATE_TEST_SUITE_P

断言类型 EXPECT(继续执行)vs ASSERT_(终止)

浮点比较 EXPECT_DOUBLE_EQ / EXPECT_NEAR

异常测试 EXPECT_THROW

CMake 集成 推荐 FetchContent 方式

八、常见问题解决

问题1: 找不到 gtest 库

解决: 使用 FetchContent 或手动编译 /usr/src/gtest

问题2: 链接错误 undefined reference

解决: 确保链接 pthread: target_link_libraries(... pthread)

问题3: 死亡测试不可用

解决: 编译时添加 -DGTEST_HAS_DEATH_TEST=1

问题4: 模板测试不编译

解决: 确保测试代码中包含完整模板定义(头文件)

这个完整示例涵盖了 Ubuntu 下 gtest 的安装、CMake 集成、模板类非虚接口测试的所有关键场景。您可以直接复制使用!

相关推荐
一段路3 分钟前
【虚拟机】Linux常用命令
linux·vim
Trouvaille ~17 分钟前
【Redis篇】Redis 哨兵(Sentinel):高可用自动故障转移
数据库·redis·缓存·中间件·sentinel·高可用·哨兵
qfljg18 分钟前
oracle 迁移到postgres
数据库·oracle
daad7771 小时前
继续记录无人机SITL的起飞
linux
giaz14n9X1 小时前
Redis 分布式锁进阶第五十七篇
数据库·redis·分布式
剑神一笑1 小时前
Linux ls 命令深度解析:从目录遍历到颜色输出的实现原理
linux·服务器·数据库
Maynor9961 小时前
Codex API 网关迁移与流量优化实战
数据库·oracle
WyCAGy8ij2 小时前
Redis 分布式锁进阶第二篇讲解
数据库·redis·分布式
南极企鹅2 小时前
MySQL的两大支柱:undo Log&redo log
数据库·mysql·oracle
智航GIS2 小时前
ArcGIS大师之路500技---078文件数据库的加密与解密
数据库·arcgis