Files
XCEngine/docs/TESTING.md

286 lines
6.8 KiB
Markdown
Raw Normal View History

# XCEngine 测试体系文档
> **版本**: 1.0
> **日期**: 2026-03-13
---
## 1. 测试架构
```
tests/
├── CMakeLists.txt # 测试构建配置
├── run_tests.cmake # 测试运行脚本
├── fixtures/ # 测试夹具
│ └── MathFixtures.h
├── math/ # Math 单元测试
│ ├── CMakeLists.txt
│ ├── test_vector.cpp
│ ├── test_matrix.cpp
│ ├── test_quaternion.cpp
│ └── test_geometry.cpp
├── core/ # Core 测试
├── threading/ # 线程测试
├── memory/ # 内存测试
├── containers/ # 容器测试
└── rendering/ # 渲染测试
├── unit/ # 单元测试
├── integration/ # 集成测试
└── screenshots/ # 参考图
```
---
## 2. 测试分类
| 类型 | 目录 | 目的 | 运行频率 |
|------|------|------|---------|
| **Unit Test** | `tests/*/` | 验证单个函数/类 | 每次提交 |
| **Integration Test** | `tests/rendering/integration/` | 验证多模块协作 | 每次提交 |
| **Benchmark** | `tests/benchmark/` | 性能回归检测 | 每日/每周 |
| **Screenshot Test** | `tests/rendering/screenshots/` | 渲染正确性 | 每次提交 |
---
## 3. 测试命名规范
```cpp
// 格式: test_<模块>_<功能>_<场景>
TEST(Math_Vector3, Dot_TwoVectors_ReturnsCorrectValue) { }
TEST(Math_Vector3, Normalize_ZeroVector_ReturnsZeroVector) { }
TEST(Math_Matrix4, Inverse_Identity_ReturnsIdentity) { }
TEST(Math_Matrix4, TRS_Decompose_RecoversOriginalValues) { }
TEST(Math_Quaternion, Slerp_ShortestPath_InterpolatesCorrectly) { }
// 边界情况
TEST(Math_Vector3, Normalize_ZeroVector_DoesNotCrash) { }
TEST(Math_Matrix4, Inverse_SingularMatrix_ReturnsIdentity) { }
```
---
## 4. 断言规范
### 4.1 浮点数比较
```cpp
// 必须使用容差
EXPECT_NEAR(actual, expected, 1e-5f);
ASSERT_FLOAT_EQ(actual, expected); // gtest 内部有容差
// 数组比较
for (int i = 0; i < 4; i++) {
EXPECT_NEAR(actual.m[i], expected.m[i], 1e-5f);
}
```
### 4.2 常用断言
```cpp
EXPECT_TRUE(condition);
EXPECT_FALSE(condition);
EXPECT_EQ(actual, expected);
EXPECT_NE(actual, expected);
EXPECT_STREQ(actual, expected);
EXPECT_THROW(expression, exception_type);
```
---
## 5. 测试夹具 (Fixture)
```cpp
class MathFixture : public ::testing::Test {
protected:
void SetUp() override {
v1 = Vector3(1, 0, 0);
v2 = Vector3(0, 1, 0);
v3 = Vector3(1, 1, 1);
m1 = Matrix4x4::Identity();
m2 = Matrix4x4::Translation(Vector3(1, 2, 3));
}
Vector3 v1, v2, v3;
Matrix4x4 m1, m2;
const float epsilon = 1e-5f;
};
TEST_F(MathFixture, Dot_OrthogonalVectors_ReturnsZero) {
EXPECT_FLOAT_EQ(Vector3::Dot(v1, v2), 0.0f);
}
```
---
## 6. 参数化测试
```cpp
class MatrixInverseTest : public ::testing::TestWithParam<Matrix4x4> {};
INSTANTIATE_TEST_SUITE_P(
InverseCases,
MatrixInverseTest,
testing::Values(
Matrix4x4::Identity(),
Matrix4x4::Translation(Vector3(1,2,3)),
Matrix4x4::Scale(Vector3(2,2,2))
)
);
TEST_P(MatrixInverseTest, InverseOfInverse_EqualsOriginal) {
Matrix4x4 original = GetParam();
Matrix4x4 inverted = original.Inverse();
Matrix4x4 recovered = inverted.Inverse();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
EXPECT_NEAR(original.m[i][j], recovered.m[i][j], 1e-4f);
}
}
}
```
---
## 7. Math 测试用例
### 7.1 Vector2/3/4 测试
| 测试类别 | 测试用例 |
|---------|---------|
| **构造** | 默认构造、参数构造、从 Vector3 构造 |
| **运算** | 加、减、乘、除、点积、叉积 |
| **归一化** | Normalize、Normalized、Magnitude、SqrMagnitude |
| **插值** | Lerp、MoveTowards |
| **投影** | Project、ProjectOnPlane |
| **角度** | Angle、Reflect |
### 7.2 Matrix 测试
| 测试类别 | 测试用例 |
|---------|---------|
| **构造** | Identity、Zero |
| **变换** | Translation、Rotation、Scale、TRS |
| **相机** | LookAt、Perspective、Orthographic |
| **运算** | 乘法、点乘、叉乘 |
| **分解** | Inverse、Transpose、Determinant、Decompose |
### 7.3 Quaternion 测试
| 测试类别 | 测试用例 |
|---------|---------|
| **构造** | Identity、FromAxisAngle、FromEulerAngles |
| **转换** | ToEulerAngles、ToMatrix4x4、FromRotationMatrix |
| **插值** | Slerp |
| **运算** | 乘法和逆 |
### 7.4 几何测试
| 测试类型 | 测试用例 |
|---------|---------|
| **Ray** | GetPoint、Intersects(Sphere/Box/Plane) |
| **Sphere** | Contains、Intersects |
| **Box** | Contains、Intersects |
| **Plane** | FromPoints、GetDistanceToPoint、Intersects |
| **Frustum** | Contains(Point/Sphere/Bounds)、Intersects |
| **Bounds** | GetMinMax、Intersects、Contains、Encapsulate |
---
## 8. 构建与运行
### 8.1 构建测试
```bash
# 创建构建目录
mkdir build && cd build
# 配置 CMake
cmake .. -G "Visual Studio 17 2022" -A x64
# 构建测试
cmake --build . --config Debug --target xcengine_math_tests
```
### 8.2 运行测试
```bash
# 运行所有测试
ctest --output-on-failure
# 运行 Math 测试
./tests/xcengine_math_tests.exe
# 运行特定测试
./tests/xcengine_math_tests.exe --gtest_filter=Math_Vector3.*
# 运行测试并显示详细信息
./tests/xcengine_math_tests.exe --gtest_also_run_disabled_tests --gtest_print_time=1
```
### 8.3 测试过滤器
```bash
# 运行所有 Vector3 测试
--gtest_filter=Math_Vector3.*
# 运行除某测试外的所有测试
--gtest_filter=-Math_Matrix4.SingularMatrix*
# 运行多个测试
--gtest_filter=Math_Vector3.*:Math_Matrix4.*
```
---
## 9. 覆盖率要求
| 模块 | 最低覆盖率 | 关键测试 |
|------|-----------|---------|
| Math | 90% | 所有公开 API |
| Core | 80% | 智能指针、Event |
| Containers | 85% | 边界、迭代器 |
| Memory | 90% | 分配/泄漏 |
| Threading | 70% | 基本功能 |
---
## 10. 持续集成
```yaml
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Configure
run: cmake -B build -DENABLE_COVERAGE=ON
- name: Build
run: cmake --build build --config Debug
- name: Test
run: ctest --test-dir build --output-on-failure
- name: Coverage
run: cmake --build build --target coverage
```
---
## 11. 注意事项
1. **浮点数比较** - 必须使用容差 (通常 1e-5 或 1e-6)
2. **边界条件** - 必须测试零向量、奇异矩阵等
3. **随机性** - 如需固定 seed 保证确定性
4. **线程安全** - 线程测试需设置超时
5. **内存泄漏** - 使用 Valgrind 或 CRT 检测