Files
XCEngine/tests/TEST_SPEC.md
ssdfasd d575532966 docs: update TEST_SPEC.md and README.md to reflect new directory structure
- TEST_SPEC.md: Updated test directory structure to reflect Core/Asset,
  Core/IO, and Resources/<Type> subdirectories
- TEST_SPEC.md: Updated module names and test counts (852 total)
- TEST_SPEC.md: Updated build commands for new Resources subdirectories
- README.md: Updated engine structure with Core/Asset/ and Core/IO/
- README.md: Updated Resources section with layered architecture
- README.md: Updated test coverage table with accurate counts
2026-03-24 16:14:05 +08:00

526 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XCEngine 测试规范
## 1. 测试框架
| 组件 | 用途 |
|------|------|
| Google Test | 单元测试框架 |
| CTest | CMake 测试发现和执行 |
---
## 2. 测试目录结构
```
tests/
├── CMakeLists.txt # 主 CMake 配置 (包含 enable_testing)
├── fixtures/ # 共享测试夹具
├── math/ # 数学库测试
├── Core/ # 核心库测试
│ ├── CMakeLists.txt
│ ├── Asset/ # Core/Asset 模块测试
│ │ ├── CMakeLists.txt
│ │ ├── test_iresource.cpp
│ │ ├── test_resource_types.cpp
│ │ ├── test_resource_guid.cpp
│ │ ├── test_resource_handle.cpp
│ │ ├── test_resource_cache.cpp
│ │ └── test_resource_dependency.cpp
│ └── IO/ # Core/IO 模块测试
│ ├── CMakeLists.txt
│ ├── test_iresource_loader.cpp
│ ├── test_resource_path.cpp
│ ├── test_resource_filesystem.cpp
│ ├── test_file_archive.cpp
│ └── test_resource_package.cpp
├── containers/ # 容器测试
├── memory/ # 内存管理测试
├── threading/ # 线程测试
├── debug/ # 调试系统测试
├── Resources/ # 资源系统测试 (按类型分目录)
│ ├── CMakeLists.txt
│ ├── Texture/ # 纹理资源测试
│ │ ├── CMakeLists.txt
│ │ ├── test_texture.cpp
│ │ ├── test_texture_loader.cpp
│ │ └── test_texture_import_settings.cpp
│ ├── Mesh/ # 网格资源测试
│ │ ├── CMakeLists.txt
│ │ ├── test_mesh.cpp
│ │ ├── test_mesh_loader.cpp
│ │ └── test_mesh_import_settings.cpp
│ ├── Material/ # 材质资源测试
│ │ ├── CMakeLists.txt
│ │ ├── test_material.cpp
│ │ └── test_material_loader.cpp
│ ├── Shader/ # 着色器资源测试
│ │ ├── CMakeLists.txt
│ │ ├── test_shader.cpp
│ │ └── test_shader_loader.cpp
│ └── AudioClip/ # 音频资源测试
│ ├── CMakeLists.txt
│ ├── test_audio_clip.cpp
│ └── test_audio_loader.cpp
├── input/ # 输入模块测试
├── scene/ # 场景测试
├── components/ # 组件测试
└── rhi/
├── CMakeLists.txt # RHI 测试主 CMake (包含 D3D12/OpenGL/unit)
├── unit/ # RHI 抽象层单元测试 (参数化, 同时测 D3D12/OpenGL)
│ ├── CMakeLists.txt
│ ├── fixtures/
│ └── test_*.cpp
├── d3d12/ # D3D12 后端封装测试
│ ├── CMakeLists.txt
│ ├── unit/ # D3D12 单元测试
│ │ ├── fixtures/
│ │ └── test_*.cpp
│ └── integration/ # D3D12 集成测试 (minimal/triangle/quad/sphere)
└── opengl/ # OpenGL 后端封装测试
├── CMakeLists.txt
├── unit/ # OpenGL 单元测试
│ ├── fixtures/
│ └── test_*.cpp
└── integration/ # OpenGL 集成测试
```
**注意**Windows 文件系统大小写不敏感,`tests/Core/``tests/core/` 为同一目录。实际文件位于 `tests/core/`(小写),但 CMakeLists.txt 中配置为 `tests/Core/`(大写)。
### 2.1 RHI 测试分层架构
RHI 测试分为三个层次,各层测试目标不同:
| 层次 | 位置 | 测试目标 | 测试方式 |
|------|------|----------|----------|
| **RHI抽象层** | `tests/RHI/unit/` | RHI接口定义、跨平台抽象、后端选择 | 参数化测试 (TEST_P),一份代码同时测试 D3D12/OpenGL |
| **D3D12后端封装** | `tests/RHI/D3D12/unit/` | D3D12 API封装实现 | 非参数化测试 (TEST_F)直接测试D3D12封装 |
| **OpenGL后端封装** | `tests/RHI/OpenGL/unit/` | OpenGL API封装实现 | 非参数化测试 (TEST_F)直接测试OpenGL封装 |
**注意**:三层测试不是冗余,而是测试不同层次的封装。各层测试可以验证:
- RHI抽象层测试验证接口兼容性和跨平台一致性
- 后端专用测试验证各后端实现的正确性
---
## 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/Texture | resources_texture_tests | Texture_* |
| Resources/Mesh | resources_mesh_tests | Mesh_* |
| Resources/Material | resources_material_tests | Material_* |
| Resources/Shader | resources_shader_tests | Shader_* |
| Resources/AudioClip | resources_audioclip_tests | AudioClip_* |
| input | input_tests | Input*/WindowsInput* |
| scene | scene_tests | Scene*/SceneManager_* |
| components | components_tests | Component_*|TransformComponent_* |
| RHI/unit (抽象层) | rhi_unit_tests | D3D12/RHITestFixture.*<br>OpenGL/RHITestFixture.* |
| RHI/D3D12 (后端) | rhi_d3d12_tests | D3D12TestFixture.*<br>SwapChainTestFixture.* |
| RHI/OpenGL (后端) | rhi_opengl_tests | OpenGLTestFixture.* |
### 3.1 RHI 参数化测试说明
`tests/RHI/unit/` 使用 Google Test 参数化测试 (TEST_P)
```cpp
// 使用 INSTANTIATE_TEST_SUITE_P 创建两个测试变体
INSTANTIATE_TEST_SUITE_P(D3D12, RHITestFixture, ::testing::Values(RHIType::D3D12));
INSTANTIATE_TEST_SUITE_P(OpenGL, RHITestFixture, ::testing::Values(RHIType::OpenGL));
// 测试名称格式: Suite/TestName/Instance
// 例如: D3D12/RHITestFixture.Buffer_Create/0
// OpenGL/RHITestFixture.Buffer_Create/0
```
**CTest 前缀说明**
- `D3D12/` - D3D12 后端实例
- `OpenGL/` - OpenGL 后端实例
---
## 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
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
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 等)
- 修改编译器选项或宏定义
**增量构建命令**
```bash
# 1. 增量配置(检测 CMakeLists.txt 变化)
cd build
cmake ..
# 2. 只构建特定 target不重新配置整个项目
cmake --build . --target math_tests --config Debug
# 3. 只构建特定模块
cmake --build . --target rhi_unit_tests --config Debug # RHI抽象层测试
cmake --build . --target rhi_d3d12_tests --config Debug # D3D12后端测试
cmake --build . --target rhi_opengl_tests --config Debug # OpenGL后端测试
```
### 6.2 完整构建
```bash
cmake --build build --config Debug
cd build && ctest -C Debug --output-on-failure
```
### 6.3 测试运行
```bash
# 列出所有测试
ctest -N
# 运行所有测试
ctest -C Debug --output-on-failure
# 运行特定模块测试
ctest -R "^Math_" -C Debug --output-on-failure
# 运行 RHI 抽象层测试 (D3D12 + OpenGL 同时测试)
ctest -R "^D3D12/|^OpenGL/" -C Debug --output-on-failure
# 只运行 RHI 抽象层的 D3D12 后端测试
ctest -R "^D3D12/" -C Debug --output-on-failure
# 只运行 RHI 抽象层的 OpenGL 后端测试
ctest -R "^OpenGL/" -C Debug --output-on-failure
# 运行 D3D12 后端专用测试
ctest -R "D3D12TestFixture|SwapChainTestFixture" -C Debug --output-on-failure
# 运行 OpenGL 后端专用测试
ctest -R "OpenGLTestFixture" -C Debug --output-on-failure
# 运行特定测试用例
ctest -R "Buffer_Create" -C Debug --output-on-failure
```
---
## 7. 测试实现规范
### 7.1 单元测试结构
```cpp
#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 配置
```yaml
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 | 25 |
| 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/Texture | ~4s | ~31s | 36 |
| Resources/Mesh | ~4s | ~31s | 29 |
| Resources/Material | ~4s | ~31s | 14 |
| Resources/Shader | ~4s | ~31s | 13 |
| Resources/AudioClip | ~4s | ~31s | 15 |
| input | ~4s | ~9s | 40 |
| RHI/unit (抽象层) | ~20s | ~60s | 138 (69×2后端) |
| D3D12 unit | ~3s | ~55s | 54 |
| OpenGL unit | ~46s | ~11s | 61 |
| **总计** | - | - | **852 (+1 disabled)** |
**注意**RHI/unit 抽象层测试数量为 69 个用例,每个用例同时在 D3D12 和 OpenGL 两个后端上执行,共 138 次测试运行。Resources 模块测试已按类型拆分到独立子目录中。
### 9.2 分模块构建命令(推荐)
```bash
# ==================== 快速开发工作流 ====================
# 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_texture_tests --config Debug
cmake --build . --target resources_mesh_tests --config Debug
cmake --build . --target resources_material_tests --config Debug
cmake --build . --target resources_shader_tests --config Debug
cmake --build . --target resources_audioclip_tests --config Debug
cmake --build . --target input_tests --config Debug
cmake --build . --target rhi_unit_tests --config Debug # RHI抽象层测试
cmake --build . --target rhi_d3d12_tests --config Debug
cmake --build . --target rhi_opengl_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 "Texture[A-Z]|Mesh[A-Z]|Shader[A-Z]|AudioClip[A-Z]|Material[A-Z]" -C Debug --output-on-failure
ctest -R "Input|WindowsInput" -C Debug --output-on-failure
ctest -R "^D3D12/|^OpenGL/" -C Debug --output-on-failure # RHI抽象层测试
ctest -R "D3D12TestFixture|SwapChainTestFixture" -C Debug --output-on-failure # D3D12后端测试
ctest -R "OpenGLTestFixture" -C Debug --output-on-failure # OpenGL后端测试
```
### 9.3 按功能组构建和运行
```bash
# ==================== 基础设施模块 ====================
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_texture_tests --config Debug
cmake --build . --target resources_mesh_tests --config Debug
cmake --build . --target resources_material_tests --config Debug
cmake --build . --target resources_shader_tests --config Debug
cmake --build . --target resources_audioclip_tests --config Debug
cmake --build . --target input_tests --config Debug
ctest -R "Component_Test|TransformComponent_|^Scene_|Texture[A-Z]|Mesh[A-Z]|Shader[A-Z]|AudioClip[A-Z]|Material[A-Z]|Input|WindowsInput" -C Debug --output-on-failure
# ==================== RHI 模块 ====================
# RHI抽象层测试 (推荐优先测试同时验证D3D12和OpenGL)
cmake --build . --target rhi_unit_tests --config Debug
ctest -R "^D3D12/|^OpenGL/" -C Debug --output-on-failure
# RHI后端专用测试 (验证特定后端实现)
cmake --build . --target rhi_d3d12_tests --config Debug
cmake --build . --target rhi_opengl_tests --config Debug
ctest -R "D3D12TestFixture|SwapChainTestFixture" -C Debug --output-on-failure
ctest -R "OpenGLTestFixture" -C Debug --output-on-failure
```
### 9.4 注意事项
- **RHI/unit 抽象层测试**:运行时间~60s138次测试69用例×2后端。推荐优先测试可快速验证接口兼容性和跨平台一致性
- **OpenGL 后端测试**:构建时间较长(~46s),因为需要编译 glad.c。建议单独构建
- **D3D12 后端测试**:运行时间较长(~55s),适合 CI 自动化
- **Resources 模块**:运行时间~31s包含大量资源加载测试
- **Math 模块**:运行时间~26s包含140个数学运算测试
---
**最后更新**: 2026-03-24
---
## 附录 A. RHI 测试分层详解
### A.1 为什么需要三层测试?
RHIRender Hardware Interface抽象层测试的目的是确保
1. **接口兼容性** - RHI定义的抽象接口在不同后端都能正常工作
2. **跨平台一致性** - 同样的代码逻辑在D3D12和OpenGL上行为一致
3. **后端实现正确性** - 各后端的封装实现符合RHI接口约定
### A.2 三层测试的关系
```
┌─────────────────────────────────────────────────────────────┐
│ RHI 抽象层测试 (unit/) │
│ TEST_P: 一份代码,验证 D3D12/OpenGL 接口兼容 │
│ 实例: D3D12/RHITestFixture.* / OpenGL/RHITestFixture.* │
└─────────────────────────────────────────────────────────────┘
┌───────────────────┴───────────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ D3D12 后端测试 │ │ OpenGL 后端测试 │
│ (D3D12/unit/) │ │ (OpenGL/unit/) │
│ TEST_F: D3D12 专用 │ │ TEST_F: OpenGL 专用 │
│ 验证 D3D12 封装实现 │ │ 验证 OpenGL 封装实现 │
└─────────────────────────┘ └─────────────────────────┘
```
### A.3 测试执行建议
| 场景 | 推荐测试 |
|------|---------|
| 日常开发 (RHI 接口验证) | `rhi_unit_tests` |
| 开发 D3D12 后端 | `rhi_unit_tests` + `rhi_d3d12_tests` |
| 开发 OpenGL 后端 | `rhi_unit_tests` + `rhi_opengl_tests` |
| CI 自动化 | `rhi_unit_tests` + `rhi_d3d12_tests` + `rhi_opengl_tests` |
### A.4 可执行文件命名规范
```
rhi_<层级>_tests
├── rhi_unit_tests # RHI抽象层测试
├── rhi_d3d12_tests # D3D12后端封装测试
└── rhi_opengl_tests # OpenGL后端封装测试
```