- Rename D3D12Enum.h to D3D12Enums.h for naming consistency - Fix OpenGL unit test GLAD initialization by using gladLoadGL() instead of gladLoadGLLoader(wglGetProcAddress) for fallback support - Migrate remaining tests to use gtest_discover_tests for granular test discovery (math, core, containers, memory, threading, debug, components, scene, resources, input, opengl) - Remove obsolete TEST_RESOURCES_DIR and copy_directory commands from OpenGL unit test CMakeLists (minimal/Res doesn't exist) - Update TEST_SPEC.md with performance metrics and per-module build/test commands for faster development workflow - Update CMake path references to use lowercase paths
9.6 KiB
9.6 KiB
XCEngine 测试规范
1. 测试框架
| 组件 | 用途 |
|---|---|
| Google Test | 单元测试框架 |
| CTest | CMake 测试发现和执行 |
2. 测试目录结构
tests/
├── CMakeLists.txt # 主 CMake 配置 (包含 enable_testing)
├── fixtures/ # 共享测试夹具
├── math/ # 数学库测试
├── core/ # 核心库测试
├── containers/ # 容器测试
├── memory/ # 内存管理测试
├── threading/ # 线程测试
├── debug/ # 调试系统测试
├── resources/ # 资源系统测试
├── input/ # 输入模块测试
├── scene/ # 场景测试
├── components/ # 组件测试
└── rhi/
├── d3d12/ # D3D12 RHI 测试
│ ├── unit/ # 单元测试
│ ├── integration/ # 集成测试
│ └── CMakeLists.txt
└── opengl/ # OpenGL RHI 测试
├── unit/ # 单元测试
├── integration/ # 集成测试
└── CMakeLists.txt
3. 模块命名
| 模块 | 可执行文件 | CTest 名称前缀 |
|---|---|---|
| math | math_tests | Math_* |
| core | core_tests | Core_* |
| containers | containers_tests | Containers_* |
| memory | memory_tests | MemoryTest_* |
| threading | threading_tests | Threading_* |
| debug | debug_tests | Debug_* |
| resources | resources_tests | Resource*/Texture*/Mesh* 等 |
| input | input_tests | Input*/WindowsInput* |
| scene | scene_tests | Scene*/SceneManager_* |
| components | components_tests | Component_* |
| RHI/D3D12 | rhi_d3d12_tests | D3D12Fixture/SwapChainFixture |
| RHI/OpenGL | opengl_engine_tests | OpenGLTestFixture.* |
4. 测试用例命名
格式: Component_Category_SubBehavior
| 部分 | 说明 | 示例 |
|---|---|---|
| Component | 被测组件 | Memory, Buffer, Texture |
| Category | 操作类别 | Create, Get, Set, Map, Reset |
| SubBehavior | 具体行为 | DefaultHeap, GPUAddress, ValidPointer |
示例:
Buffer_Create_DefaultHeap
Texture_Create_2D
Fence_Signal_Wait
禁止模式:
*_Placeholder- 无意义的占位测试- 驼峰+下划线混用
5. CMake 规范
5.1 单元测试模板
cmake_minimum_required(VERSION 3.15)
find_package(GTest REQUIRED)
set(TEST_SOURCES
test_module.cpp
)
add_executable(module_tests ${TEST_SOURCES})
if(MSVC)
set_target_properties(module_tests PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib"
)
endif()
target_link_libraries(module_tests PRIVATE
XCEngine
GTest::gtest
GTest::gtest_main
)
target_include_directories(module_tests PRIVATE
${CMAKE_SOURCE_DIR}/engine/include
${CMAKE_SOURCE_DIR}/tests/fixtures
)
include(GoogleTest)
gtest_discover_tests(module_tests)
5.2 RHI 测试 CMakeLists 模板
cmake_minimum_required(VERSION 3.15)
project(rhi_backend_tests)
find_package(GTest REQUIRED)
find_package(Python3 REQUIRED) # 集成测试需要
# 单元测试
set(UNIT_TEST_SOURCES
fixtures/TestFixture.cpp
test_*.cpp
)
add_executable(rhi_backend_tests ${UNIT_TEST_SOURCES})
target_link_libraries(rhi_backend_tests PRIVATE
d3d12
dxgi
d3dcompiler
XCEngine
GTest::gtest
GTest::gtest_main
)
target_include_directories(rhi_backend_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/fixtures
${CMAKE_SOURCE_DIR}/engine/include
${CMAKE_SOURCE_DIR}/engine/src
)
# 集成测试
add_subdirectory(integration)
include(GoogleTest)
gtest_discover_tests(rhi_backend_tests)
6. 测试执行
6.1 增量构建(推荐)
何时需要重新运行 cmake ..:
- 新增/删除/重命名源文件
- 修改 CMakeLists.txt(添加 subdirectory、target 等)
- 修改编译器选项或宏定义
增量构建命令:
# 1. 增量配置(检测 CMakeLists.txt 变化)
cd build
cmake ..
# 2. 只构建特定 target(不重新配置整个项目)
cmake --build . --target math_tests --config Debug
# 3. 只构建特定模块
cmake --build . --target rhi_d3d12_tests --config Debug
6.2 完整构建
cmake --build build --config Debug
cd build && ctest -C Debug --output-on-failure
6.3 测试运行
# 列出所有测试
ctest -N
# 运行所有测试
ctest -C Debug --output-on-failure
# 运行特定模块测试
ctest -R "Math_" -C Debug --output-on-failure
# 运行 D3D12 所有测试
ctest -R "D3D12" -C Debug --output-on-failure
# 运行特定测试用例
ctest -R "Buffer_Create" -C Debug --output-on-failure
7. 测试实现规范
7.1 单元测试结构
#include <gtest/gtest.h>
#include <XCEngine/Module/Component.h>
class ComponentTest : public ::testing::Test {
protected:
void SetUp() override { }
void TearDown() override { }
};
TEST_F(ComponentTest, Create_ReturnsValidPointer) {
auto component = Component::Create();
ASSERT_NE(component, nullptr);
}
7.2 断言选择
| 断言 | 用途 |
|---|---|
ASSERT_* |
致命错误,立即终止测试 |
EXPECT_* |
非致命错误,继续执行 |
8. CI 配置
name: XCEngine Tests
on: [push, pull_request]
jobs:
test:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Configure CMake
run: cmake -B build -DCMAKE_BUILD_TYPE=Debug
- name: Build
run: cmake --build build --config Debug
- name: Run Tests
run: cd build && ctest -C Debug --output-on-failure
9. 性能参考
9.1 模块构建和运行时间
| 模块 | 构建时间 | 运行时间 | 测试数量 |
|---|---|---|---|
| math | ~6s | ~26s | 140 |
| core | ~6s | ~4s | 18 |
| containers | ~3s | ~10s | 51 |
| memory | ~3s | ~4s | 19 |
| threading | ~5s | ~4s | 13 |
| debug | ~3s | ~2s | 8 |
| components | ~3s | ~8s | 39 |
| scene | ~4s | ~2s | 14 |
| resources | ~4s | ~31s | 131 |
| input | ~4s | ~9s | 40 |
| D3D12 unit | ~3s | ~55s | 49 |
| OpenGL unit | ~46s | ~11s | 61 |
| 总计 | - | - | ~622 |
9.2 分模块构建命令(推荐)
# ==================== 快速开发工作流 ====================
# 1. 修改某个模块代码后,增量构建该模块
cmake --build . --target math_tests --config Debug
cmake --build . --target core_tests --config Debug
cmake --build . --target containers_tests --config Debug
cmake --build . --target memory_tests --config Debug
cmake --build . --target threading_tests --config Debug
cmake --build . --target debug_tests --config Debug
cmake --build . --target components_tests --config Debug
cmake --build . --target scene_tests --config Debug
cmake --build . --target resources_tests --config Debug
cmake --build . --target input_tests --config Debug
cmake --build . --target rhi_d3d12_tests --config Debug
cmake --build . --target opengl_engine_tests --config Debug
# 2. 只运行该模块测试
ctest -R "^Math_" -C Debug --output-on-failure
ctest -R "^Core_" -C Debug --output-on-failure
ctest -R "^Containers_" -C Debug --output-on-failure
ctest -R "MemoryTest_|LinearAllocator|PoolAllocator" -C Debug --output-on-failure
ctest -R "^Threading_" -C Debug --output-on-failure
ctest -R "^Debug_" -C Debug --output-on-failure
ctest -R "Component_Test|TransformComponent_" -C Debug --output-on-failure
ctest -R "^Scene_" -C Debug --output-on-failure
ctest -R "Resource[A-Z]|Texture[A-Z]|Mesh[A-Z]|Shader[A-Z]|Audio[A-Z]|Material[A-Z]" -C Debug --output-on-failure
ctest -R "Input|WindowsInput" -C Debug --output-on-failure
ctest -R "D3D12.*Fixture|SwapChain.*Fixture" -C Debug --output-on-failure
build/tests/RHI/OpenGL/unit/Debug/opengl_engine_tests.exe --gtest_filter=*
9.3 按功能组构建和运行
# ==================== 基础设施模块 ====================
cmake --build . --target math_tests --config Debug
cmake --build . --target core_tests --config Debug
cmake --build . --target containers_tests --config Debug
ctest -R "^Math_|^Core_|^Containers_" -C Debug --output-on-failure
# ==================== 核心系统模块 ====================
cmake --build . --target memory_tests --config Debug
cmake --build . --target threading_tests --config Debug
cmake --build . --target debug_tests --config Debug
ctest -R "MemoryTest_|LinearAllocator|PoolAllocator|^Threading_|^Debug_" -C Debug --output-on-failure
# ==================== 游戏引擎模块 ====================
cmake --build . --target components_tests --config Debug
cmake --build . --target scene_tests --config Debug
cmake --build . --target resources_tests --config Debug
cmake --build . --target input_tests --config Debug
ctest -R "Component_Test|TransformComponent_|^Scene_|Resource[A-Z]|Texture[A-Z]|Mesh[A-Z]|Input|WindowsInput" -C Debug --output-on-failure
# ==================== RHI 模块 ====================
cmake --build . --target rhi_d3d12_tests --config Debug
cmake --build . --target opengl_engine_tests --config Debug
ctest -R "D3D12.*Fixture|SwapChain.*Fixture" -C Debug --output-on-failure
build/tests/RHI/OpenGL/unit/Debug/opengl_engine_tests.exe --gtest_filter=*
9.4 注意事项
- OpenGL 单元测试:构建时间较长(~46s),因为需要编译 glad.c。建议单独构建
- D3D12 单元测试:运行时间较长(~55s),适合 CI 自动化
- Resources 模块:运行时间~31s,包含大量资源加载测试
- Math 模块:运行时间~26s,包含140个数学运算测试
最后更新: 2026-03-23