C++ 测试:单元测试、集成测试、端到端测试——高级水平

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 高级测试:从单元测试到端到端测试

在现代 C++ 开发中,代码质量不仅取决于其性能,还取决于其可靠性。高级测试远远超出了简单的检查范畴——它是一种架构方法,包括单元测试、集成测试和端到端 (e2e) 测试。在本文中,我们将探讨如何为 C++ 项目正确构建测试金字塔,使用 Google Test、Google Mock 和自定义框架。



1. 单元测试:隔离与模拟

单元测试在隔离环境中测试单个模块(函数、类)。在高级水平上,关键任务是学会正确模拟依赖项。让我们看一个使用 Google Mock 的示例。



假设我们有一个类 DatabaseConnector,它依赖于外部 API。我们希望在无需访问真实数据库的情况下测试数据处理逻辑。



#include <gmock/gmock.h>#include <gtest/gtest.h>

class DatabaseInterface {public: virtual ~DatabaseInterface() = default; virtual std::string fetchData(int id) = 0;};

class MockDatabase : public DatabaseInterface {public: MOCK_METHOD(std::string, fetchData, (int id), (override));};

class DataProcessor { DatabaseInterface& db;public: explicit DataProcessor(DatabaseInterface& db) : db(db) {} std::string process(int id) { auto raw = db.fetchData(id); if (raw.empty()) return "EMPTY"; return "PROCESSED: " + raw; }};

TEST(DataProcessorTest, ProcessWithValidData) { MockDatabase mockDb; EXPECT_CALL(mockDb, fetchData(42)) .WillOnce(testing::Return("Hello")); DataProcessor processor(mockDb); EXPECT_EQ(processor.process(42), "PROCESSED: Hello");}


使用 MOCK_METHOD 可以精确控制依赖项的行为。重要的是要记住使用严格模拟(通过 NiceMock 或 StrictMock)来捕获意外调用。



2. 集成测试:测试交互

集成测试检查模块如何协同工作。在 C++ 中,这通常包括测试与文件系统、网络协议或数据库的交互。高级方法是使用测试夹具和参数化测试。



示例:测试一个读写文件的类 FileManager。我们使用临时目录。



class FileManagerTest : public ::testing::Test {protected:    std::filesystem::path tempDir;    void SetUp() override {        tempDir = std::filesystem::temp_directory_path() / "test_files";        std::filesystem::create_directories(tempDir);    }    void TearDown() override {        std::filesystem::remove_all(tempDir);    }};

TEST_F(FileManagerTest, WriteAndReadFile) { FileManager fm(tempDir.string()); fm.write("test.txt", "data"); auto content = fm.read("test.txt"); EXPECT_EQ(content, "data");}


对于参数化测试,我们使用 TEST_P 配合 INSTANTIATE_TEST_SUITE_P。这允许使用不同的输入数据运行同一个测试。



class MathTest : public ::testing::TestWithParam<std::tuple<int, int, int>> {};TEST_P(MathTest, Add) {    auto [a, b, expected] = GetParam();    EXPECT_EQ(add(a, b), expected);}INSTANTIATE_TEST_SUITE_P(AddTests, MathTest,    ::testing::Values(        std::make_tuple(1, 1, 2),        std::make_tuple(-1, 1, 0),        std::make_tuple(0, 0, 0)    ));


3. 端到端测试:验证完整流程

端到端测试模拟最终用户的行为。对于 C++ 应用程序,这可能意味着运行完整的二进制文件、检查其输出或通过 API 进行交互。高级水平

博客

书籍推荐