Files
XCEngine/tests/TEST_SPEC.md
ssdfasd d1b7fda816 docs: Update TEST_SPEC.md with RHI integration tests documentation
- Add integration test directory structure
- Expand test hierarchy from 3 to 4 layers (add integration tests)
- Update module naming table with integration test executables
- Add integration test execution commands
- Add integration test performance references
- Update appendix A with 4-layer architecture diagram
- Update total test count to 860
2026-03-25 18:59:40 +08:00

22 KiB
Raw Blame History

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/integration)
    ├── 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 集成测试 (minimal/triangle/quad/sphere)

注意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封装
集成测试 tests/RHI/*/integration/ 多组件协作、渲染管线完整性 Python脚本对比渲染输出PPM文件

注意:四层测试不是冗余,而是测试不同层次的封装。各层测试可以验证:

  • 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_*
RHI/unit (抽象层) rhi_unit_tests D3D12/RHITestFixture.
OpenGL/RHITestFixture.
RHI/D3D12/unit (后端) rhi_d3d12_tests D3D12TestFixture.
SwapChainTestFixture.
RHI/OpenGL/unit (后端) rhi_opengl_tests OpenGLTestFixture.*
RHI/D3D12/integration d3d12_*_test d3d12_minimal_test
d3d12_triangle_test
d3d12_quad_test
d3d12_sphere_test
RHI/OpenGL/integration opengl_*_test opengl_minimal_test
opengl_triangle_test
opengl_quad_test
opengl_sphere_test

3.1 RHI 参数化测试说明

tests/RHI/unit/ 使用 Google Test 参数化测试 (TEST_P)

// 使用 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_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_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 完整构建

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

# 运行 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

# 运行 D3D12 集成测试
ctest -R "d3d12_minimal_test|d3d12_triangle_test|d3d12_quad_test|d3d12_sphere_test" -C Debug --output-on-failure

# 运行 OpenGL 集成测试
ctest -R "opengl_minimal_test|opengl_triangle_test|opengl_quad_test|opengl_sphere_test" -C Debug --output-on-failure

# 运行所有 RHI 测试 (单元 + 集成)
ctest -R "d3d12_|opengl_|D3D12/|OpenGL/" -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 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
D3D12 integration ~10s ~20s 4
OpenGL integration ~60s ~20s 4
总计 - - 860 (+1 disabled)

注意

  • RHI/unit 抽象层测试数量为 69 个用例,每个用例同时在 D3D12 和 OpenGL 两个后端上执行,共 138 次测试运行
  • 集成测试包含 minimal/triangle/quad/sphere 四个场景,每个后端各 4 个
  • Resources 模块测试已按类型拆分到独立子目录中

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_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
cmake --build . --target d3d12_minimal_test --config Debug  # D3D12集成测试
cmake --build . --target d3d12_triangle_test --config Debug
cmake --build . --target d3d12_quad_test --config Debug
cmake --build . --target d3d12_sphere_test --config Debug
cmake --build . --target opengl_minimal_test --config Debug  # OpenGL集成测试
cmake --build . --target opengl_triangle_test --config Debug
cmake --build . --target opengl_quad_test --config Debug
cmake --build . --target opengl_sphere_test --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后端测试
ctest -R "d3d12_minimal_test|d3d12_triangle_test|d3d12_quad_test|d3d12_sphere_test" -C Debug --output-on-failure  # D3D12集成测试
ctest -R "opengl_minimal_test|opengl_triangle_test|opengl_quad_test|opengl_sphere_test" -C Debug --output-on-failure  # OpenGL集成测试

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_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

# RHI集成测试 (验证完整渲染管线)
cmake --build . --target d3d12_minimal_test --config Debug
cmake --build . --target d3d12_triangle_test --config Debug
cmake --build . --target d3d12_quad_test --config Debug
cmake --build . --target d3d12_sphere_test --config Debug
cmake --build . --target opengl_minimal_test --config Debug
cmake --build . --target opengl_triangle_test --config Debug
cmake --build . --target opengl_quad_test --config Debug
cmake --build . --target opengl_sphere_test --config Debug
ctest -R "d3d12_minimal_test|d3d12_triangle_test|d3d12_quad_test|d3d12_sphere_test" -C Debug --output-on-failure
ctest -R "opengl_minimal_test|opengl_triangle_test|opengl_quad_test|opengl_sphere_test" -C Debug --output-on-failure

9.4 注意事项

  • RHI/unit 抽象层测试:运行时间~60s138次测试69用例×2后端。推荐优先测试可快速验证接口兼容性和跨平台一致性
  • OpenGL 后端测试:构建时间较长(~46s),因为需要编译 glad.c。建议单独构建
  • D3D12 后端测试:运行时间较长(~55s),适合 CI 自动化
  • RHI 集成测试:需要 GPU 环境,渲染输出与基准 PPM 文件对比。OpenGL 构建时间较长因为需要编译 glad.c
  • Resources 模块:运行时间~31s包含大量资源加载测试
  • Math 模块:运行时间~26s包含140个数学运算测试

最后更新: 2026-03-25


附录 A. RHI 测试分层详解

A.1 为什么需要四层测试?

RHIRender Hardware Interface抽象层测试的目的是确保

  1. 接口兼容性 - RHI定义的抽象接口在不同后端都能正常工作
  2. 跨平台一致性 - 同样的代码逻辑在D3D12和OpenGL上行为一致
  3. 后端实现正确性 - 各后端的封装实现符合RHI接口约定
  4. 渲染管线完整性 - 多组件协作和完整渲染流程正确性

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 封装实现   │
└─────────────────────────┘         └─────────────────────────┘
                               │
           ┌───────────────────┴───────────────────┐
           ▼                                       ▼
┌─────────────────────────┐         ┌─────────────────────────┐
│   D3D12 集成测试          │         │   OpenGL 集成测试        │
│   (D3D12/integration/)   │         │   (OpenGL/integration/) │
│   minimal/triangle/      │         │   minimal/triangle/     │
│   quad/sphere            │         │   quad/sphere            │
│   Python脚本对比PPM       │         │   Python脚本对比PPM       │
└─────────────────────────┘         └─────────────────────────┘

A.3 测试执行建议

场景 推荐测试
日常开发 (RHI 接口验证) rhi_unit_tests
开发 D3D12 后端 rhi_unit_tests + rhi_d3d12_tests
开发 OpenGL 后端 rhi_unit_tests + rhi_opengl_tests
验证渲染管线 D3D12/OpenGL 集成测试
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后端封装测试
└── <backend>_<scene>_test     # 集成测试 (如 d3d12_minimal_test)