# SimpleRemoter 测试架构 本文档描述项目的测试架构、框架选择和最佳实践。 ## 目录 - [测试框架](#测试框架) - [目录结构](#目录结构) - [测试分类](#测试分类) - [命名规范](#命名规范) - [编写指南](#编写指南) - [运行测试](#运行测试) - [CI/CD 集成](#cicd-集成) ## 测试框架 ### Google Test (gtest) 项目采用 [Google Test](https://github.com/google/googletest) 作为主要测试框架。 **选择理由:** | 特性 | 说明 | |------|------| | 功能完整 | 支持断言、Mock、参数化测试、死亡测试 | | 跨平台 | Windows/Linux 均可使用 | | VS 集成 | Visual Studio Test Explorer 直接支持 | | CI 友好 | 输出 JUnit XML 格式,CI 系统可直接解析 | | 社区活跃 | 文档完善,问题易解决 | ### 版本要求 - Google Test: 1.14.0+ - CMake: 3.14+ - C++: 17+ (使用结构化绑定等特性) - Visual Studio: 2019 或 2022 ## 目录结构 ``` SimpleRemoter/ ├── test/ # 测试根目录 │ ├── CMakeLists.txt # 测试构建配置 (14 个测试可执行文件) │ ├── test.bat # Windows 测试管理脚本 │ ├── unit/ # 单元测试 │ │ ├── client/ # 客户端模块测试 │ │ │ └── BufferTest.cpp # 客户端 Buffer (33 用例) ✅ │ │ ├── server/ # 服务端模块测试 │ │ │ └── BufferTest.cpp # 服务端 Buffer (40 用例) ✅ │ │ ├── protocol/ # 协议层测试 (Phase 1) │ │ │ ├── PacketTest.cpp # 文件传输包 (39 用例) ✅ │ │ │ └── PathUtilsTest.cpp # 路径处理 (19 用例) ✅ │ │ ├── file/ # 文件传输测试 (Phase 2) │ │ │ ├── FileTransferV2Test.cpp # V2 传输逻辑 (37 用例) ✅ │ │ │ ├── ChunkManagerTest.cpp # 分块管理 (36 用例) ✅ │ │ │ ├── SHA256VerifyTest.cpp # SHA-256 校验 (28 用例) ✅ │ │ │ └── ResumeStateTest.cpp # 断点续传状态 (26 用例) ✅ │ │ ├── network/ # 网络通信测试 (Phase 3) │ │ │ ├── HeaderTest.cpp # 协议头验证 (29 用例) ✅ │ │ │ ├── PacketFragmentTest.cpp # 粘包/分包 (24 用例) ✅ │ │ │ └── HttpMaskTest.cpp # HTTP 伪装 (27 用例) ✅ │ │ └── screen/ # 图像处理测试 (Phase 4) │ │ ├── DiffAlgorithmTest.cpp # 差分算法 (32 用例) ✅ │ │ ├── RGB565Test.cpp # RGB565 压缩 (286 用例) ✅ │ │ ├── ScrollDetectorTest.cpp # 滚动检测 (43 用例) ✅ │ │ └── QualityAdaptiveTest.cpp # 质量自适应 (64 用例) ✅ │ ├── integration/ # 集成测试 (待实现) │ ├── mocks/ # Mock 对象 (待实现) │ └── fixtures/ # 测试数据/夹具 (待实现) ├── docs/ │ └── TestingArchitecture.md # 本文档 └── ... ``` ## 测试分类 ### 单元测试 (Unit Tests) 测试单个类或函数的独立功能。 **特点:** - 快速执行(毫秒级) - 无外部依赖(网络、文件系统等) - 高覆盖率目标(>80%) **示例:** ```cpp TEST(BufferTest, WriteBuffer_ValidData_ReturnsTrue) { CBuffer buffer; BYTE data[] = {1, 2, 3}; EXPECT_TRUE(buffer.WriteBuffer(data, 3)); EXPECT_EQ(buffer.GetBufferLength(), 3); } ``` ### 集成测试 (Integration Tests) 测试多个组件的协作。 **特点:** - 测试组件间交互 - 可能涉及真实资源 - 执行时间较长 ### 端到端测试 (E2E Tests) 测试完整的用户场景。 **特点:** - 模拟真实使用场景 - 客户端 ↔ 服务端完整流程 - 执行时间最长 ## 命名规范 ### 测试文件 ``` Test.cpp 例:BufferTest.cpp, FileManagerTest.cpp ``` ### 测试套件 ``` Test 例:TEST(BufferTest, ...) ``` ### 测试用例 采用 `MethodName_StateUnderTest_ExpectedBehavior` 格式: ```cpp // 好的命名 TEST(BufferTest, ReadBuffer_WhenBufferEmpty_ReturnsZero) TEST(BufferTest, WriteBuffer_ExceedsCapacity_ReallocatesMemory) TEST(BufferTest, Skip_ExceedsDataLength_ClampsToAvailable) // 避免的命名 TEST(BufferTest, Test1) TEST(BufferTest, ReadWorks) ``` ## 编写指南 ### AAA 模式 所有测试应遵循 Arrange-Act-Assert 模式: ```cpp TEST(BufferTest, ReadBuffer_PartialRead_ReturnsRequestedLength) { // Arrange - 准备测试数据和对象 CBuffer buffer; BYTE writeData[] = {1, 2, 3, 4, 5}; buffer.WriteBuffer(writeData, 5); // Act - 执行被测操作 BYTE readData[3]; ULONG bytesRead = buffer.ReadBuffer(readData, 3); // Assert - 验证结果 EXPECT_EQ(bytesRead, 3); EXPECT_EQ(readData[0], 1); EXPECT_EQ(readData[1], 2); EXPECT_EQ(readData[2], 3); EXPECT_EQ(buffer.GetBufferLength(), 2); } ``` ### 边界条件测试 确保覆盖边界情况: ```cpp // 空缓冲区 TEST(BufferTest, ReadBuffer_EmptyBuffer_ReturnsZero) // 零长度操作 TEST(BufferTest, WriteBuffer_ZeroLength_ReturnsTrue) // 请求超过可用数据 TEST(BufferTest, ReadBuffer_RequestExceedsAvailable_ReturnsAvailableOnly) // 大数据量 TEST(BufferTest, WriteBuffer_LargeData_HandlesCorrectly) ``` ### 参数化测试 对于需要多组数据验证的场景: ```cpp class BufferReadTest : public ::testing::TestWithParam> {}; TEST_P(BufferReadTest, ReadBuffer_VariousLengths) { auto [writeLen, readLen, expectedRead] = GetParam(); CBuffer buffer; std::vector data(writeLen, 0x42); buffer.WriteBuffer(data.data(), writeLen); std::vector result(readLen); ULONG actual = buffer.ReadBuffer(result.data(), readLen); EXPECT_EQ(actual, expectedRead); } INSTANTIATE_TEST_SUITE_P( ReadLengths, BufferReadTest, ::testing::Values( std::make_tuple(10, 5, 5), // 正常读取 std::make_tuple(5, 10, 5), // 请求超过可用 std::make_tuple(0, 5, 0), // 空缓冲区 std::make_tuple(100, 0, 0) // 零长度读取 ) ); ``` ### 线程安全测试(服务端 Buffer) ```cpp TEST(ServerBufferTest, ConcurrentReadWrite_NoDataCorruption) { CBuffer buffer; std::atomic running{true}; // 写线程 std::thread writer([&]() { BYTE data[100]; while (running) { buffer.WriteBuffer(data, sizeof(data)); } }); // 读线程 std::thread reader([&]() { BYTE data[50]; while (running) { buffer.ReadBuffer(data, sizeof(data)); } }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); running = false; writer.join(); reader.join(); // 验证无崩溃即为成功 SUCCEED(); } ``` ## 运行测试 ### 使用 test.bat (推荐) Windows 下最简单的方式是使用 `test.bat` 脚本: ```batch cd test test.bat build # 构建测试 (14 个可执行文件) test.bat run # 运行所有测试 (763 个) test.bat run client # 只运行客户端 Buffer 测试 (33) test.bat run server # 只运行服务端 Buffer 测试 (40) test.bat run protocol # 只运行协议测试 (58) test.bat run file # 只运行文件传输测试 (127) test.bat run network # 只运行网络通信测试 (80) test.bat run screen # 只运行图像处理测试 (425) test.bat run verbose # 详细模式运行 test.bat clean # 清理构建目录 test.bat rebuild # 清理后重新构建 test.bat help # 显示帮助 ``` ### CMake 手动构建 ```bash cd test # 配置 cmake -B build -G "Visual Studio 17 2022" # 构建 cmake --build build --config Release # 运行所有测试 ctest --test-dir build -C Release --output-on-failure # 运行特定测试 ctest --test-dir build -C Release -R Client # 客户端测试 ctest --test-dir build -C Release -R Server # 服务端测试 # 详细输出 ctest --test-dir build -C Release -V ``` ### 直接运行可执行文件 ```batch :: Phase 1: Buffer 测试 test\build\Release\client_buffer_test.exe test\build\Release\server_buffer_test.exe :: Phase 1: 协议测试 test\build\Release\protocol_test.exe :: Phase 2: 文件传输测试 test\build\Release\file_transfer_test.exe test\build\Release\chunk_manager_test.exe test\build\Release\sha256_verify_test.exe test\build\Release\resume_state_test.exe :: Phase 3: 网络通信测试 test\build\Release\header_test.exe test\build\Release\packet_fragment_test.exe test\build\Release\http_mask_test.exe :: Phase 4: 图像处理测试 test\build\Release\diff_algorithm_test.exe test\build\Release\rgb565_test.exe test\build\Release\scroll_detector_test.exe test\build\Release\quality_adaptive_test.exe :: 使用 gtest 过滤器 header_test.exe --gtest_filter="*Encrypt*" rgb565_test.exe --gtest_filter="*Conversion*" :: 列出所有测试(不运行) quality_adaptive_test.exe --gtest_list_tests :: 输出 XML 报告 protocol_test.exe --gtest_output=xml:report.xml ``` ## CI/CD 集成 ### GitHub Actions 示例 ```yaml name: Tests on: [push, pull_request] jobs: test: runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: Configure CMake working-directory: test run: cmake -B build -G "Visual Studio 17 2022" - name: Build working-directory: test run: cmake --build build --config Release - name: Run Tests working-directory: test run: ctest --test-dir build -C Release --output-on-failure - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results path: test/build/Release/*.xml ``` ## 覆盖率 ### 使用 gcov/lcov (Linux) ```bash # 配置(启用覆盖率) cmake -B build -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_CXX_FLAGS="--coverage" # 构建并运行测试 cmake --build build ctest --test-dir build # 生成报告 lcov --capture --directory build --output-file coverage.info genhtml coverage.info --output-directory coverage_report ``` ## 当前测试状态 **总计: 763 个测试用例,全部通过** ✅ (执行时间 < 3 秒) ### 已覆盖模块 | 阶段 | 模块 | 测试文件 | 用例数 | 状态 | |------|------|----------|--------|------| | Phase 1 | 客户端 Buffer | `unit/client/BufferTest.cpp` | 33 | ✅ | | Phase 1 | 服务端 Buffer | `unit/server/BufferTest.cpp` | 40 | ✅ | | Phase 1 | 协议/数据包 | `unit/protocol/PacketTest.cpp` | 39 | ✅ | | Phase 1 | 路径处理 | `unit/protocol/PathUtilsTest.cpp` | 19 | ✅ | | Phase 2 | V2 文件传输 | `unit/file/FileTransferV2Test.cpp` | 37 | ✅ | | Phase 2 | 分块管理 | `unit/file/ChunkManagerTest.cpp` | 36 | ✅ | | Phase 2 | SHA-256 校验 | `unit/file/SHA256VerifyTest.cpp` | 28 | ✅ | | Phase 2 | 断点续传 | `unit/file/ResumeStateTest.cpp` | 26 | ✅ | | Phase 3 | 协议头验证 | `unit/network/HeaderTest.cpp` | 29 | ✅ | | Phase 3 | 粘包/分包 | `unit/network/PacketFragmentTest.cpp` | 24 | ✅ | | Phase 3 | HTTP 伪装 | `unit/network/HttpMaskTest.cpp` | 27 | ✅ | | Phase 4 | 差分算法 | `unit/screen/DiffAlgorithmTest.cpp` | 32 | ✅ | | Phase 4 | RGB565 压缩 | `unit/screen/RGB565Test.cpp` | 286 | ✅ | | Phase 4 | 滚动检测 | `unit/screen/ScrollDetectorTest.cpp` | 43 | ✅ | | Phase 4 | 质量自适应 | `unit/screen/QualityAdaptiveTest.cpp` | 64 | ✅ | | | **合计** | | **763** | ✅ | ### 测试分布概览 | 阶段 | 测试类别 | 用例数 | 说明 | |------|---------|--------|------| | Phase 1 | Buffer 操作 | 73 | 读写、跳过、边界、线程安全 | | Phase 1 | 协议解析 | 58 | V2 数据包、路径处理 | | Phase 2 | 文件传输 | 127 | 分块、续传、校验 | | Phase 3 | 网络通信 | 80 | 包头、分包、伪装 | | Phase 4 | 图像处理 | 425 | 差分、RGB565、滚动、自适应 | ### 待测试模块 | 优先级 | 模块 | 说明 | |-------|------|------| | 中 | 系统管理 | 进程列表、服务管理 | | 中 | 终端 | 命令解析、输出处理 | | 低 | 压缩模块 | zstd 压缩/解压 | ## 参考资料 - [Google Test 官方文档](https://google.github.io/googletest/) - [Google Mock 入门](https://google.github.io/googletest/gmock_for_dummies.html) - [C++ 单元测试最佳实践](https://github.com/cpp-best-practices/cppbestpractices/blob/master/08-Considering_Safety.md)