docs: restructure test specification into two-level system
- tests/TEST_SPEC.md: General test spec for all modules - tests/RHI/D3D12/TEST_SPEC.md: D3D12-specific spec with CI integration
This commit is contained in:
@@ -1,82 +1,52 @@
|
|||||||
# D3D12 测试规范文档
|
# D3D12 测试专项规范
|
||||||
|
|
||||||
## 1. 测试分类
|
本文档是 XCEngine 测试规范的 D3D12 专项补充。
|
||||||
|
|
||||||
### 1.1 测试层级
|
**前置阅读**: [tests/TEST_SPEC.md](../TEST_SPEC.md) - 通用测试规范
|
||||||
|
|
||||||
| 层级 | 位置 | 执行方式 | 目的 |
|
|
||||||
|------|------|----------|------|
|
|
||||||
| 单元测试 | `tests/RHI/D3D12/unit/` | CTest 自动运行 | 验证各组件 API 功能 |
|
|
||||||
| 集成测试 | `tests/RHI/D3D12/integration/` | CTest + Python wrapper | 端到端渲染验证 |
|
|
||||||
|
|
||||||
### 1.2 单元测试规范
|
|
||||||
|
|
||||||
**框架**: Google Test
|
|
||||||
**运行方式**:
|
|
||||||
```bash
|
|
||||||
cd build/tests/RHI/D3D12/unit
|
|
||||||
ctest -C Debug --output-on-failure
|
|
||||||
```
|
|
||||||
|
|
||||||
**命名约定**: `Component_Category_SubBehavior`
|
|
||||||
- Component: 组件名 (Device, Buffer, Texture, CommandQueue, etc.)
|
|
||||||
- Category: 操作类别 (Create, Get, Set, Map, Reset, etc.)
|
|
||||||
- SubBehavior: 具体行为 (DefaultHeap, GPUAddress, etc.)
|
|
||||||
|
|
||||||
**示例**:
|
|
||||||
```
|
|
||||||
Device_Create_Success
|
|
||||||
Device_Get_AdapterInfo
|
|
||||||
Buffer_Create_DefaultHeap
|
|
||||||
Buffer_Map_Unmap
|
|
||||||
Texture_Create_2D
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1.3 集成测试规范
|
|
||||||
|
|
||||||
**运行方式**: Python wrapper 通过 CTest 调用
|
|
||||||
```bash
|
|
||||||
cd build/tests/RHI/D3D12/integration
|
|
||||||
ctest -C Debug --output-on-failure
|
|
||||||
```
|
|
||||||
|
|
||||||
**Python Wrapper 职责**:
|
|
||||||
1. 启动 D3D12 exe
|
|
||||||
2. 等待进程完成
|
|
||||||
3. 检查输出文件
|
|
||||||
4. 调用 compare_ppm.py 比对 Golden Image
|
|
||||||
5. 返回 0(成功)/1(失败)
|
|
||||||
|
|
||||||
**Golden Image 规范**:
|
|
||||||
- 文件格式: PPM (P6)
|
|
||||||
- 存储位置: `tests/RHI/D3D12/integration/`
|
|
||||||
- 命名: `GT_<test_name>.ppm`
|
|
||||||
- 阈值: 默认 5%
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 测试命名规则
|
## 1. 概述
|
||||||
|
|
||||||
### 2.1 禁止模式
|
### 1.1 D3D12 测试特点
|
||||||
|
|
||||||
❌ 不允许:
|
| 特点 | 说明 |
|
||||||
- `*_Placeholder` - 无意义的占位测试
|
|------|------|
|
||||||
- 驼峰+下划线混用
|
| 硬件依赖 | 需要支持 D3D12 的显卡 |
|
||||||
- 空操作测试
|
| 窗口依赖 | 集成测试需要 GUI 窗口 |
|
||||||
|
| GPU 状态 | 测试间可能有 GPU 状态污染 |
|
||||||
|
|
||||||
### 2.2 标准格式
|
### 1.2 测试层级
|
||||||
|
|
||||||
✅ 正确格式:
|
| 层级 | 位置 | 执行方式 | 框架 |
|
||||||
```
|
|------|------|----------|------|
|
||||||
Component_Category_SubBehavior
|
| 单元测试 | `tests/RHI/D3D12/unit/` | CTest | Google Test |
|
||||||
|
| 集成测试 | `tests/RHI/D3D12/integration/` | CTest + Python | Python wrapper |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 单元测试规范
|
||||||
|
|
||||||
|
### 2.1 Fixture 设计
|
||||||
|
|
||||||
|
每个测试独立创建设备,避免 GPU 状态污染:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class D3D12TestFixture : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
void SetUp() override; // 创建设备、命令队列等
|
||||||
|
void TearDown() override; // 清理资源
|
||||||
|
|
||||||
|
ID3D12Device* GetDevice();
|
||||||
|
ID3D12CommandQueue* GetCommandQueue();
|
||||||
|
ID3D12CommandAllocator* GetCommandAllocator();
|
||||||
|
ID3D12GraphicsCommandList* GetCommandList();
|
||||||
|
|
||||||
|
void WaitForGPU();
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.3 大小写规则
|
### 2.2 测试前缀对应
|
||||||
|
|
||||||
- 全小写,单词间用下划线分隔
|
|
||||||
- Component 名称与类名一致 (如 `CommandQueue` 不是 `Command_queue`)
|
|
||||||
|
|
||||||
### 2.4 测试前缀对应关系
|
|
||||||
|
|
||||||
| 类名 | 测试前缀 |
|
| 类名 | 测试前缀 |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
@@ -94,227 +64,159 @@ Component_Category_SubBehavior
|
|||||||
| D3D12RenderTargetView | RTV |
|
| D3D12RenderTargetView | RTV |
|
||||||
| D3D12DepthStencilView | DSV |
|
| D3D12DepthStencilView | DSV |
|
||||||
|
|
||||||
---
|
### 2.3 当前测试统计
|
||||||
|
|
||||||
## 3. 测试实现规范
|
| 组件 | 测试数 | 状态 |
|
||||||
|
|------|--------|------|
|
||||||
### 3.1 单元测试结构
|
| Device | 6 | ✅ 通过 |
|
||||||
|
| Fence | 5 | ✅ 通过 |
|
||||||
```cpp
|
| CommandQueue | 2 | ✅ 通过 |
|
||||||
TEST_F(D3D12TestFixture, Component_Category_SubBehavior) {
|
| CommandAllocator | 3 | ✅ 通过 |
|
||||||
// Arrange: 准备测试数据
|
| CommandList | 2 | ✅ 通过 |
|
||||||
|
| Buffer | 5 | ✅ 通过 |
|
||||||
// Act: 执行被测操作
|
| Texture | 4 | ✅ 通过 |
|
||||||
|
| DescriptorHeap | 5 | ✅ 通过 |
|
||||||
// Assert: 验证结果
|
| PipelineState | 2 | ✅ 通过 |
|
||||||
ASSERT_TRUE(condition);
|
| RootSignature | 2 | ✅ 通过 |
|
||||||
EXPECT_EQ(expected, actual);
|
| Shader | 3 | ✅ 通过 |
|
||||||
}
|
| Views | 4 | ✅ 通过 |
|
||||||
```
|
| **总计** | **44** | **全部通过** |
|
||||||
|
|
||||||
### 3.2 Fixture 使用
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
class D3D12TestFixture : public ::testing::Test {
|
|
||||||
protected:
|
|
||||||
void SetUp() override; // 创建设备、命令队列等
|
|
||||||
void TearDown() override; // 清理资源
|
|
||||||
|
|
||||||
ID3D12Device* GetDevice();
|
|
||||||
ID3D12CommandQueue* GetCommandQueue();
|
|
||||||
ID3D12CommandAllocator* GetCommandAllocator();
|
|
||||||
ID3D12GraphicsCommandList* GetCommandList();
|
|
||||||
|
|
||||||
void WaitForGPU();
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.3 错误处理测试
|
|
||||||
|
|
||||||
对于负面测试:
|
|
||||||
```cpp
|
|
||||||
TEST_F(D3D12TestFixture, Component_Create_InvalidSize) {
|
|
||||||
// 测试零大小或负数大小应该失败
|
|
||||||
ASSERT_FALSE(buffer->Initialize(device, 0));
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. 集成测试规范
|
## 3. 集成测试规范
|
||||||
|
|
||||||
### 4.1 Python Wrapper 模板
|
### 3.1 Python Wrapper
|
||||||
|
|
||||||
```python
|
**位置**: `tests/RHI/D3D12/integration/run_integration_test.py`
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
|
|
||||||
def run_integration_test(exe_path, output_ppm, gt_ppm, threshold, timeout=120):
|
**职责**:
|
||||||
"""
|
1. 启动 D3D12 exe
|
||||||
Run a D3D12 integration test and compare output with golden template.
|
2. 等待进程完成
|
||||||
|
3. 检查输出文件 (PPM 截图)
|
||||||
Args:
|
4. 调用 `compare_ppm.py` 比对 Golden Image
|
||||||
exe_path: Path to the test executable
|
5. 返回 0(成功)/1(失败)
|
||||||
output_ppm: Filename of the output screenshot
|
|
||||||
gt_ppm: Path to the golden template PPM file
|
|
||||||
threshold: Pixel difference threshold for comparison
|
|
||||||
timeout: Maximum time to wait (seconds)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
0 on success, non-zero on failure
|
|
||||||
"""
|
|
||||||
# 1. 检查文件存在
|
|
||||||
# 2. 删除旧输出
|
|
||||||
# 3. 启动进程
|
|
||||||
# 4. 等待完成
|
|
||||||
# 5. 检查输出
|
|
||||||
# 6. 比对图片
|
|
||||||
# 7. 返回结果
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 CTest 注册格式
|
### 3.2 CTest 注册格式
|
||||||
|
|
||||||
```cmake
|
```cmake
|
||||||
find_package(Python3 REQUIRED)
|
find_package(Python3 REQUIRED)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
add_test(NAME TestName
|
add_test(NAME D3D12_Minimal_Integration
|
||||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
|
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
|
||||||
$<TARGET_FILE:TargetName>
|
$<TARGET_FILE:D3D12_Minimal>
|
||||||
output.ppm
|
minimal.ppm
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
|
${CMAKE_CURRENT_SOURCE_DIR}/GT_minimal.ppm
|
||||||
5
|
5
|
||||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:TargetName>
|
WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_Minimal>
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.3 Golden Image 生成
|
### 3.3 Golden Image 规范
|
||||||
|
|
||||||
|
| 属性 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| 格式 | PPM (P6) |
|
||||||
|
| 命名 | `GT_<test_name>.ppm` |
|
||||||
|
| 阈值 | 默认 5% |
|
||||||
|
| 存储位置 | `tests/RHI/D3D12/integration/` |
|
||||||
|
|
||||||
|
### 3.4 Golden Image 生成流程
|
||||||
|
|
||||||
1. 在干净硬件环境运行集成测试
|
1. 在干净硬件环境运行集成测试
|
||||||
2. 截图保存为 `GT_<name>.ppm`
|
2. 截图保存为 `GT_<name>.ppm`
|
||||||
3. 人工验证截图正确性
|
3. 人工验证截图正确性
|
||||||
4. 提交到版本控制
|
4. 提交到版本控制
|
||||||
|
|
||||||
---
|
### 3.5 当前集成测试
|
||||||
|
|
||||||
## 5. CMakeLists.txt 规范
|
| 测试名 | Golden Image | 状态 |
|
||||||
|
|--------|-------------|------|
|
||||||
### 5.1 单元测试 CMakeLists.txt
|
| D3D12_Minimal_Integration | GT_minimal.ppm | ✅ 通过 |
|
||||||
|
| D3D12_RenderModel_Integration | GT.ppm | ❌ 待修复 |
|
||||||
```cmake
|
|
||||||
cmake_minimum_required(VERSION 3.15)
|
|
||||||
get_filename_component(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. ABSOLUTE)
|
|
||||||
|
|
||||||
find_package(GTest REQUIRED)
|
|
||||||
|
|
||||||
set(TEST_SOURCES
|
|
||||||
fixtures/D3D12TestFixture.cpp
|
|
||||||
test_device.cpp
|
|
||||||
test_buffer.cpp
|
|
||||||
# ... 其他测试文件
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(d3d12_engine_tests ${TEST_SOURCES})
|
|
||||||
|
|
||||||
target_link_libraries(d3d12_engine_tests PRIVATE
|
|
||||||
d3d12
|
|
||||||
dxgi
|
|
||||||
d3dcompiler
|
|
||||||
XCEngine
|
|
||||||
GTest::gtest
|
|
||||||
GTest::gtest_main
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(d3d12_engine_tests PRIVATE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/fixtures
|
|
||||||
${PROJECT_ROOT_DIR}/engine/include
|
|
||||||
${PROJECT_ROOT_DIR}/engine/src
|
|
||||||
)
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
add_test(NAME D3D12EngineTests COMMAND d3d12_engine_tests)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 集成测试 CMakeLists.txt
|
|
||||||
|
|
||||||
```cmake
|
|
||||||
cmake_minimum_required(VERSION 3.15)
|
|
||||||
project(D3D12_Integration)
|
|
||||||
|
|
||||||
set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/../engine)
|
|
||||||
find_package(Python3 REQUIRED)
|
|
||||||
enable_testing()
|
|
||||||
|
|
||||||
add_executable(D3D12_Test WIN32 main.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(D3D12_Test PRIVATE
|
|
||||||
d3d12 dxgi d3dcompiler winmm XCEngine
|
|
||||||
)
|
|
||||||
|
|
||||||
# POST_BUILD: 复制资源文件
|
|
||||||
add_custom_command(TARGET D3D12_Test POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Res
|
|
||||||
$<TARGET_FILE_DIR:D3D12_Test>/Res
|
|
||||||
)
|
|
||||||
|
|
||||||
# CTest 注册
|
|
||||||
add_test(NAME D3D12_Test_Integration
|
|
||||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
|
|
||||||
$<TARGET_FILE:D3D12_Test>
|
|
||||||
output.ppm
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
|
|
||||||
5
|
|
||||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_Test>
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. 测试执行
|
## 4. 测试执行
|
||||||
|
|
||||||
### 6.1 完整测试流程
|
### 4.1 单元测试
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. 构建
|
# 方式 1: 使用统一脚本
|
||||||
cd build
|
python scripts/run_tests.py --unit-only
|
||||||
cmake ..
|
|
||||||
cmake --build . --target d3d12_engine_tests D3D12_Test --config Debug
|
|
||||||
|
|
||||||
# 2. 运行单元测试
|
# 方式 2: 直接使用 CTest
|
||||||
cd tests/RHI/D3D12/unit
|
cd build/tests/RHI/D3D12/unit
|
||||||
ctest -C Debug --output-on-failure
|
|
||||||
|
|
||||||
# 3. 运行集成测试
|
|
||||||
cd tests/RHI/D3D12/integration
|
|
||||||
ctest -C Debug --output-on-failure
|
ctest -C Debug --output-on-failure
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 输出格式
|
### 4.2 集成测试
|
||||||
|
|
||||||
成功:
|
```bash
|
||||||
```
|
# 方式 1: 使用统一脚本
|
||||||
Test #1: D3D12_Minimal_Integration ....... Passed
|
python scripts/run_tests.py --integration
|
||||||
|
|
||||||
|
# 方式 2: 直接使用 CTest
|
||||||
|
cd build/tests/RHI/D3D12/integration
|
||||||
|
ctest -C Debug --output-on-failure
|
||||||
```
|
```
|
||||||
|
|
||||||
失败:
|
### 4.3 构建和测试
|
||||||
```
|
|
||||||
Test #1: D3D12_Minimal_Integration ....... Failed
|
```bash
|
||||||
[Integration Test] Different pixels: 39.94%
|
# 构建
|
||||||
FAIL: Images differ!
|
cmake --build . --target d3d12_engine_tests D3D12_Minimal --config Debug
|
||||||
|
|
||||||
|
# 运行测试
|
||||||
|
python scripts/run_tests.py --build
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. 文件结构
|
## 5. CI 集成
|
||||||
|
|
||||||
|
### 5.1 GitHub Actions 配置
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: D3D12 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 D3D12 Tests
|
||||||
|
run: cmake --build build --target d3d12_engine_tests D3D12_Minimal --config Debug
|
||||||
|
|
||||||
|
- name: Run Unit Tests
|
||||||
|
run: cd build/tests/RHI/D3D12/unit && ctest -C Debug --output-on-failure
|
||||||
|
|
||||||
|
- name: Run Integration Tests
|
||||||
|
run: python scripts/run_tests.py --integration
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 CI 模式
|
||||||
|
|
||||||
|
`--ci` 模式会跳过需要 GUI 的集成测试:
|
||||||
|
```bash
|
||||||
|
python scripts/run_tests.py --ci # 仅运行单元测试
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 文件结构
|
||||||
|
|
||||||
```
|
```
|
||||||
tests/RHI/D3D12/
|
tests/RHI/D3D12/
|
||||||
├── CMakeLists.txt
|
├── CMakeLists.txt
|
||||||
├── TEST_IMPROVEMENT_PLAN.md # 改进计划
|
├── TEST_SPEC.md # 本文档 (D3D12 专项)
|
||||||
├── TEST_SPEC.md # 本规范
|
├── TEST_IMPROVEMENT_PLAN.md # 改进计划
|
||||||
├── unit/
|
├── unit/
|
||||||
│ ├── CMakeLists.txt
|
│ ├── CMakeLists.txt
|
||||||
│ ├── fixtures/
|
│ ├── fixtures/
|
||||||
@@ -326,7 +228,7 @@ tests/RHI/D3D12/
|
|||||||
└── integration/
|
└── integration/
|
||||||
├── CMakeLists.txt
|
├── CMakeLists.txt
|
||||||
├── main_minimal.cpp
|
├── main_minimal.cpp
|
||||||
├── main_render.cpp
|
├── main_render.cpp # 有 API 问题,待修复
|
||||||
├── run_integration_test.py
|
├── run_integration_test.py
|
||||||
├── compare_ppm.py
|
├── compare_ppm.py
|
||||||
├── GT.ppm
|
├── GT.ppm
|
||||||
@@ -335,13 +237,27 @@ tests/RHI/D3D12/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 7. 已知问题
|
||||||
|
|
||||||
|
### 7.1 main_render.cpp API 不兼容
|
||||||
|
|
||||||
|
**问题**: `D3D12Buffer::Initialize` 和 `D3D12Screenshot::Capture` API 签名变更
|
||||||
|
|
||||||
|
**影响**: `D3D12_RenderModel_Integration` 无法编译
|
||||||
|
|
||||||
|
**状态**: 待修复
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 8. 规范更新记录
|
## 8. 规范更新记录
|
||||||
|
|
||||||
| 版本 | 日期 | 变更 |
|
| 版本 | 日期 | 变更 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 1.0 | 2026-03-20 | 初始版本 |
|
| 1.0 | 2026-03-20 | 初始版本 |
|
||||||
|
| 1.1 | 2026-03-20 | 添加 CI 集成章节,补充 Phase 5 内容 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**规范版本**: 1.0
|
**规范版本**: 1.1
|
||||||
**最后更新**: 2026-03-20
|
**最后更新**: 2026-03-20
|
||||||
|
**前置文档**: [tests/TEST_SPEC.md](../TEST_SPEC.md)
|
||||||
328
tests/TEST_SPEC.md
Normal file
328
tests/TEST_SPEC.md
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
# XCEngine 测试规范
|
||||||
|
|
||||||
|
## 1. 测试框架
|
||||||
|
|
||||||
|
### 1.1 框架组成
|
||||||
|
|
||||||
|
| 组件 | 用途 | 文档位置 |
|
||||||
|
|------|------|---------|
|
||||||
|
| Google Test | 单元测试框架 | https://google.github.io/googletest/ |
|
||||||
|
| CTest | CMake 测试发现和执行 | 内置 CMake 模块 |
|
||||||
|
| Python | 集成测试辅助 | `scripts/run_tests.py` |
|
||||||
|
|
||||||
|
### 1.2 测试分类
|
||||||
|
|
||||||
|
| 类型 | 框架 | 特点 |
|
||||||
|
|------|------|------|
|
||||||
|
| 单元测试 | Google Test | 快速、独立、无副作用 |
|
||||||
|
| 集成测试 | CTest + Python | 端到端验证、需要 GUI |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 测试目录结构
|
||||||
|
|
||||||
|
### 2.1 整体结构
|
||||||
|
|
||||||
|
```
|
||||||
|
tests/
|
||||||
|
├── CMakeLists.txt # 主 CMake 配置
|
||||||
|
├── TEST_SPEC.md # 本规范文档
|
||||||
|
├── run_tests.bat # Windows 测试启动脚本
|
||||||
|
├── fixtures/ # 共享测试夹具
|
||||||
|
├── scripts/
|
||||||
|
│ └── run_tests.py # 统一测试运行脚本
|
||||||
|
├── math/ # 数学库测试
|
||||||
|
├── core/ # 核心库测试
|
||||||
|
├── containers/ # 容器测试
|
||||||
|
├── memory/ # 内存管理测试
|
||||||
|
├── threading/ # 线程测试
|
||||||
|
├── debug/ # 调试系统测试
|
||||||
|
├── Resources/ # 资源系统测试
|
||||||
|
└── RHI/
|
||||||
|
├── D3D12/ # D3D12 RHI 测试
|
||||||
|
│ ├── unit/ # 单元测试
|
||||||
|
│ └── integration/ # 集成测试
|
||||||
|
└── OpenGL/ # OpenGL RHI 测试 (暂不维护)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 模块命名规范
|
||||||
|
|
||||||
|
| 模块 | 测试可执行文件 | CTest 名称 |
|
||||||
|
|------|--------------|-----------|
|
||||||
|
| math | xcengine_math_tests | MathTests |
|
||||||
|
| core | xcengine_core_tests | CoreTests |
|
||||||
|
| containers | xcengine_containers_tests | ContainersTests |
|
||||||
|
| memory | xcengine_memory_tests | MemoryTests |
|
||||||
|
| threading | xcengine_threading_tests | ThreadingTests |
|
||||||
|
| debug | xcengine_debug_tests | DebugTests |
|
||||||
|
| Resources | xcengine_resources_tests | ResourcesTests |
|
||||||
|
| RHI/D3D12/unit | d3d12_engine_tests | D3D12EngineTests |
|
||||||
|
| RHI/D3D12/integration | D3D12_Minimal | D3D12_Minimal_Integration |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 测试命名规范
|
||||||
|
|
||||||
|
### 3.1 单元测试命名
|
||||||
|
|
||||||
|
**格式**: `Component_Category_SubBehavior`
|
||||||
|
|
||||||
|
| 部分 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| Component | 被测组件 | Memory, ResourceHandle, Buffer |
|
||||||
|
| Category | 操作类别 | Create, Get, Set, Map, Reset |
|
||||||
|
| SubBehavior | 具体行为 | DefaultHeap, GPUAddress, ValidPointer |
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
MemoryTest_GetSystemAllocator_ReturnsValidPointer
|
||||||
|
ResourceHandle_DefaultConstructor
|
||||||
|
Buffer_Create_DefaultHeap
|
||||||
|
Texture_Create_2D
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 禁止模式
|
||||||
|
|
||||||
|
❌ 不允许:
|
||||||
|
- `*_Placeholder` - 无意义的占位测试
|
||||||
|
- 驼峰+下划线混用
|
||||||
|
- 空操作测试
|
||||||
|
|
||||||
|
### 3.3 大小写规则
|
||||||
|
|
||||||
|
- 全小写,单词间用下划线分隔
|
||||||
|
- Component 名称与类名一致
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. CMakeLists.txt 规范
|
||||||
|
|
||||||
|
### 4.1 单元测试模板
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
|
project(XCEngine_ModuleTests)
|
||||||
|
|
||||||
|
find_package(GTest REQUIRED)
|
||||||
|
|
||||||
|
set(TEST_SOURCES
|
||||||
|
test_module.cpp
|
||||||
|
# ... 其他测试文件
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(xcengine_module_tests ${TEST_SOURCES})
|
||||||
|
|
||||||
|
# MSVC 运行时库排除
|
||||||
|
if(MSVC)
|
||||||
|
set_target_properties(xcengine_module_tests PROPERTIES
|
||||||
|
LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(xcengine_module_tests PRIVATE
|
||||||
|
XCEngine
|
||||||
|
GTest::gtest
|
||||||
|
GTest::gtest_main
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(xcengine_module_tests PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/engine/include
|
||||||
|
${CMAKE_SOURCE_DIR}/tests/fixtures
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME ModuleTests COMMAND xcengine_module_tests)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 CTest 注册
|
||||||
|
|
||||||
|
每个模块的 CMakeLists.txt 必须包含:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
add_test(NAME <TestName> COMMAND <executable>)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 测试资源复制
|
||||||
|
|
||||||
|
如需复制测试资源:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
add_custom_command(TARGET <test> POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Res
|
||||||
|
$<TARGET_FILE_DIR:<test>>/Res
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 测试执行
|
||||||
|
|
||||||
|
### 5.1 统一测试脚本
|
||||||
|
|
||||||
|
**位置**: `scripts/run_tests.py`
|
||||||
|
|
||||||
|
**功能**:
|
||||||
|
- 跨平台支持 (Windows/Linux)
|
||||||
|
- 自动检测测试目录
|
||||||
|
- 单元测试 + 集成测试
|
||||||
|
- 测试结果汇总
|
||||||
|
|
||||||
|
### 5.2 使用方式
|
||||||
|
|
||||||
|
| 命令 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `python scripts/run_tests.py` | 运行所有测试 |
|
||||||
|
| `python scripts/run_tests.py --unit-only` | 仅单元测试 |
|
||||||
|
| `python scripts/run_tests.py --integration` | 含集成测试 |
|
||||||
|
| `python scripts/run_tests.py --ci` | CI 模式 (跳过 GUI 测试) |
|
||||||
|
| `python scripts/run_tests.py --build` | 构建并测试 |
|
||||||
|
| `python scripts/run_tests.py --dir <path>` | 指定测试目录 |
|
||||||
|
| `python scripts/run_tests.py --verbose` | 详细输出 |
|
||||||
|
|
||||||
|
### 5.3 直接使用 CTest
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行特定模块测试
|
||||||
|
cd build/tests/<module>
|
||||||
|
ctest -C Debug --output-on-failure
|
||||||
|
|
||||||
|
# 列出所有测试
|
||||||
|
ctest -N
|
||||||
|
|
||||||
|
# 运行所有测试
|
||||||
|
ctest -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. CI 集成
|
||||||
|
|
||||||
|
### 6.1 GitHub Actions 配置
|
||||||
|
|
||||||
|
```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: python scripts/run_tests.py --ci
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 CI 模式说明
|
||||||
|
|
||||||
|
`--ci` 模式会:
|
||||||
|
- 运行所有单元测试
|
||||||
|
- 跳过需要 GUI 窗口的集成测试
|
||||||
|
- 输出机器可读的测试结果
|
||||||
|
|
||||||
|
### 6.3 本地验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 完整构建和测试
|
||||||
|
python scripts/run_tests.py --build
|
||||||
|
|
||||||
|
# 仅验证单元测试
|
||||||
|
python scripts/run_tests.py --unit-only
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 测试实现规范
|
||||||
|
|
||||||
|
### 7.1 单元测试结构
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <XCEngine/Module/Component.h>
|
||||||
|
|
||||||
|
using namespace XCEngine::Module;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ComponentTest, GetProperty_ReturnsExpectedValue) {
|
||||||
|
Component component;
|
||||||
|
EXPECT_EQ(component.GetProperty(), expected_value);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 Fixture 使用原则
|
||||||
|
|
||||||
|
- 每个测试类使用独立的 Fixture
|
||||||
|
- SetUp/TearDown 用于资源初始化/清理
|
||||||
|
- 避免测试间共享状态
|
||||||
|
|
||||||
|
### 7.3 断言选择
|
||||||
|
|
||||||
|
| 断言 | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `ASSERT_*` | 致命错误,立即终止测试 |
|
||||||
|
| `EXPECT_*` | 非致命错误,继续执行 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
tests/
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── TEST_SPEC.md # 本规范
|
||||||
|
├── run_tests.bat # Windows 测试脚本
|
||||||
|
├── fixtures/ # 共享夹具头文件
|
||||||
|
├── scripts/
|
||||||
|
│ └── run_tests.py # 统一测试运行脚本
|
||||||
|
├── math/
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ └── test_*.cpp
|
||||||
|
├── core/
|
||||||
|
├── containers/
|
||||||
|
├── memory/
|
||||||
|
├── threading/
|
||||||
|
├── debug/
|
||||||
|
├── Resources/
|
||||||
|
└── RHI/
|
||||||
|
├── D3D12/
|
||||||
|
│ ├── unit/
|
||||||
|
│ ├── integration/
|
||||||
|
│ ├── TEST_SPEC.md # D3D12 专项规范
|
||||||
|
│ └── TEST_IMPROVEMENT_PLAN.md
|
||||||
|
└── OpenGL/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 规范更新记录
|
||||||
|
|
||||||
|
| 版本 | 日期 | 变更 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1.0 | 2026-03-20 | 初始版本,统一测试规范体系 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**规范版本**: 1.0
|
||||||
|
**最后更新**: 2026-03-20
|
||||||
Reference in New Issue
Block a user