Unified logging: Replace LogSystem with EditorConsoleSink
- Created EditorConsoleSink (implements ILogSink interface) - EditorConsoleSink stores logs in memory buffer (max 1000 entries) - Added to Debug::Logger in Application::Initialize() - ConsolePanel now reads from EditorConsoleSink via static GetInstance() - Removed separate LogSystem singleton - Removed editor/src/Core/LogEntry.h (no longer needed) Now Editor and Engine share the same Debug::Logger, with ConsolePanel displaying logs via EditorConsoleSink.
This commit is contained in:
285
docs/used/TESTING.md
Normal file
285
docs/used/TESTING.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# 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 检测
|
||||
Reference in New Issue
Block a user