# WhuCPPTestProject01 **Repository Path**: lgc653/whu-cpptest-project01 ## Basic Information - **Project Name**: WhuCPPTestProject01 - **Description**: 武汉大学计算机学院-大一-devops实训案例: 测试相关: 集成测试、性能测试技术; * 测试文档规范 * 使用mock进行测试数据模拟 * 使用curl和swagger进行Restful接口测试 * 使用JMeter进行接口性能测试 * 使用puppeteer进行前端功能、性能测试 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-07-13 - **Last Updated**: 2026-07-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HelloCrow — C++ Web 服务 + 全链路自动化测试 教学案例 一个麻雀虽小五脏俱全的 C++ Web 后端教学项目,覆盖 **vcpkg 依赖管理 → 编码实现 → GMock 单元测试 → httplib 集成测试 → Puppeteer 前端功能/性能测试** 全流程。 ## 项目结构 ``` CPPTestProject01/ ├── CMakeLists.txt # 构建配置(find_package + vcpkg) ├── CMakePresets.json # cmake --preset default 一键配置 ├── vcpkg.json # 依赖声明(crow, gtest, cpp-httplib) ├── src/ │ └── main.cpp # 服务器全部代码(~80 行) ├── tests/ │ └── test_basic.cpp # 单元测试(GMock)+ 集成测试(httplib) ├── scripts/ │ ├── package.json # Puppeteer 依赖 │ └── test_frontend.js # 前端功能 + 性能测试 ├── static/ │ └── index.html # 前端页面 └── README.md ``` ## 技术栈 | 组件 | 用途 | |------|------| | **Crow** | C++ 微 Web 框架(路由 + JSON + 中间件 + 静态文件) | | **GTest/GMock** | 单元测试框架(`MOCK_METHOD` + `EXPECT_CALL` 模拟依赖) | | **cpp-httplib** | 单头文件 HTTP 客户端(集成测试发真实请求) | | **Puppeteer** | 无头浏览器(前端功能验证 + 性能指标采集) | | **vcpkg** | C++ 包管理器(清单模式,一条命令安装所有依赖) | | **CMake** | 跨平台构建系统 | ## 快速开始 ### 前提条件 - CMake ≥ 3.20 - C++17 编译器(MSVC 2019+ / GCC 9+ / Clang 10+) - [vcpkg](https://github.com/microsoft/vcpkg)(本项目使用 `F:/vcpkg`) - Node.js(仅前端测试需要) ### 1. 安装 C++ 依赖 ```bash # vcpkg 自动读取 vcpkg.json,首次会下载编译,之后秒级完成 vcpkg install ``` ### 2. 编译 ```bash # 预设已配置 vcpkg 路径,无需手动指定 -DCMAKE_TOOLCHAIN_FILE=... cmake --preset default cmake --build build ``` ### 3. 启动服务器 ```bash cd build/Debug ./hello_crow.exe ``` 打开浏览器访问 `http://localhost:18080`,即可看到前端页面。 ### 4. 运行 C++ 测试 ```bash # 直接运行 ./build/Debug/hello_test.exe # 或通过 CTest ctest --test-dir build --output-on-failure ``` 预期输出: ``` [==========] Running 7 tests from 2 test suites. [----------] 3 tests from GreeterServiceTest ← GMock 单元测试 [ OK ] GreeterServiceTest.SayHello_ReturnsGreeting [ OK ] GreeterServiceTest.SayHello_EmptyName_DefaultsToWorld [ OK ] GreeterServiceTest.SayHello_CallsGreetExactlyOnce [----------] 4 tests from IntegrationTest ← httplib 集成测试 [ OK ] IntegrationTest.HelloEndpoint_ReturnsJson [ OK ] IntegrationTest.HelloEndpoint_NoName_DefaultsToWorld [ OK ] IntegrationTest.CountEndpoint_ReturnsCount [ OK ] IntegrationTest.UnknownEndpoint_Returns404 [==========] 7 tests from 2 test suites ran. (1272 ms total) [ PASSED ] 7 tests. ``` ### 5. 运行前端测试(Puppeteer) ```bash cd scripts npm install # 首次执行 node test_frontend.js # 全部测试(功能 + 性能) node test_frontend.js --functional # 仅功能测试 node test_frontend.js --performance # 仅性能测试 ``` 预期输出: ``` ============================================================ 功能测试 (Functional Tests) 5/5 ✓ ============================================================ [Test 1] 页面加载 PASS 标题: "HelloCrow - C++ Web 服务演示" [Test 2] 默认 Hello PASS {"message":"Hello, World!"} [Test 3] 自定义名字 PASS {"message":"Hello, Puppeteer!"} [Test 4] 统计接口 PASS total_requests > 0 [Test 5] 404 错误处理 PASS status: 404 ============================================================ 性能测试 (Performance Tests) 3/3 ✓ ============================================================ [Perf 1] 页面加载性能 PASS TTFB=1ms, FCP=68ms, Load=50ms [Perf 2] API 响应时间 PASS /api/hello avg=14ms, /api/count avg=16ms [Perf 3] 截图保存 PASS test_result.png ``` ## 测试全景图 ``` ┌─────────────────────────────────────────────────────────┐ │ 全链路测试矩阵 │ ├──────────────┬──────────────┬──────────────┬────────────┤ │ 测试层级 │ 工具 │ 测试数量 │ 耗时 │ ├──────────────┼──────────────┼──────────────┼────────────┤ │ 单元测试 │ GMock │ 3 个 │ < 5ms │ │ 集成测试 │ httplib │ 4 个 │ ~1300ms │ │ 前端功能测试 │ Puppeteer │ 5 个 │ ~800ms │ │ 前端性能测试 │ Puppeteer │ 3 个 │ ~1200ms │ ├──────────────┼──────────────┼──────────────┼────────────┤ │ 总计 │ │ 15 个 │ 全部通过 │ └──────────────┴──────────────┴──────────────┴────────────┘ ``` ## API 端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/hello?name=XXX` | 返回问候 JSON(name 可选,默认 World) | | GET | `/api/count` | 返回请求计数 + 服务器时间 | | GET | `/` | 静态首页 | ```bash # Hello 接口 curl "http://localhost:18080/api/hello?name=C%2B%2B" # → {"message":"Hello, C++!","time":"2026-07-12T03:00:00Z"} # 不传参数默认 World curl "http://localhost:18080/api/hello" # → {"message":"Hello, World!","time":"2026-07-12T03:00:00Z"} # 统计接口(用于性能压测) curl "http://localhost:18080/api/count" # → {"total_requests":42,"server_time":"2026-07-12T03:00:00Z"} ``` ## 核心概念解析 ### 1. 为什么需要 Mock? ``` 没有 Mock: 测试 → Service → 数据库(慢、状态污染) 用 Mock: 测试 → Service → Mock对象(快、完全可控) ``` Mock 把"依赖"替换成"假对象",让单元测试只测当前层的逻辑,不受外部系统影响。 ### 2. GMock 三步法 ```cpp // ① 定义 Mock 类(一行搞定 — MOCK_METHOD 宏自动生成所有脚手架代码) class MockGreeter : public IGreeter { public: MOCK_METHOD(std::string, greet, (const std::string&), (const, override)); }; // ② 设定期望:当 greet("Alice") 被调用时,返回 "Hello, Alice!" MockGreeter mock; EXPECT_CALL(mock, greet("Alice")).WillOnce(Return("Hello, Alice!")); // ③ 依赖注入 → 调用被测方法 → 断言结果 GreeterService service(&mock); EXPECT_EQ(service.sayHello("Alice"), "Hello, Alice!"); // GMock 在测试结束时自动验证 greet("Alice") 确实被调用了 1 次 ``` ### 3. 依赖注入(Dependency Injection) ```cpp // 高层模块不依赖低层实现,两者都依赖抽象接口 class GreeterService { const IGreeter* greeter_; // 只依赖接口,不依赖具体实现 public: explicit GreeterService(const IGreeter* g) : greeter_(g) {} // ... }; // 生产环境注入真实实现 GreeterService service(new RealGreeter()); // 测试环境注入 Mock GreeterService service(new MockGreeter()); ``` ### 4. 测试金字塔 ``` /\ /PP\ Puppeteer(少量,端到端验证) /────\ / 集成 \ httplib(中等,组件协作验证) /────────\ / 单元测试 \ GMock(大量,快速、精准定位) /────────────\ ``` ## 文件说明 | 文件 | 内容 | |------|------| | [src/main.cpp](src/main.cpp) | 服务器全部代码:全局计数器、2 个 API 端点、静态文件服务 | | [tests/test_basic.cpp](tests/test_basic.cpp) | C++ 测试:Part 1 GMock 演示(接口→Mock→注入→验证),Part 2 TestServerHelper + httplib 集成测试 | | [scripts/test_frontend.js](scripts/test_frontend.js) | Puppeteer 测试:功能验证(5 项)+ 性能采集(TTFB/FCP/API 延迟/截图) | | [static/index.html](static/index.html) | 前端页面:`fetch()` 调用后端 API,展示 JSON 响应 | | [vcpkg.json](vcpkg.json) | vcpkg 清单模式依赖声明 | | [CMakePresets.json](CMakePresets.json) | CMake 预设,固化 vcpkg toolchain 路径 |