mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-06 16:16:44 +08:00
fix(game-tests): 收敛配置与序列化测试告警
- 修复架构配置、启动流程与序列化测试中的异步等待和 invariant 解析告警 - 补充 AllOf 与 persistence 测试的残余状态校验与 ConfigureAwait 修正,继续压低 Game.Tests warning - 更新 analyzer-warning-reduction 跟踪与 trace,纠正 RP-054 的 stop-condition 口径并记录 RP-055 指标
This commit is contained in:
parent
36507bbc52
commit
5aefd77ad0
@ -39,7 +39,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
try
|
||||
{
|
||||
architecture = new ConsumerArchitecture(rootPath);
|
||||
await architecture.InitializeAsync();
|
||||
await architecture.InitializeAsync().ConfigureAwait(false);
|
||||
initialized = true;
|
||||
|
||||
var table = architecture.MonsterTable;
|
||||
@ -63,7 +63,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
{
|
||||
if (architecture is not null && initialized)
|
||||
{
|
||||
await architecture.DestroyAsync();
|
||||
await architecture.DestroyAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
DeleteDirectoryIfExists(rootPath);
|
||||
@ -83,7 +83,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
try
|
||||
{
|
||||
architecture = new ConsumerArchitecture(rootPath);
|
||||
await architecture.InitializeAsync();
|
||||
await architecture.InitializeAsync().ConfigureAwait(false);
|
||||
initialized = true;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
@ -97,7 +97,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
{
|
||||
if (architecture is not null && initialized)
|
||||
{
|
||||
await architecture.DestroyAsync();
|
||||
await architecture.DestroyAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
DeleteDirectoryIfExists(rootPath);
|
||||
@ -119,16 +119,16 @@ public class ArchitectureConfigIntegrationTests
|
||||
var module = CreateModule(rootPath);
|
||||
|
||||
firstArchitecture = new ModuleOnlyArchitecture(module);
|
||||
await firstArchitecture.InitializeAsync();
|
||||
await firstArchitecture.InitializeAsync().ConfigureAwait(false);
|
||||
var wasInitializedBeforeDestroy = module.IsInitialized;
|
||||
await firstArchitecture.DestroyAsync();
|
||||
await firstArchitecture.DestroyAsync().ConfigureAwait(false);
|
||||
firstDestroyed = true;
|
||||
firstArchitecture = null;
|
||||
GameContext.Clear();
|
||||
|
||||
var secondArchitecture = new ModuleOnlyArchitecture(module);
|
||||
var exception =
|
||||
Assert.ThrowsAsync<InvalidOperationException>(async () => await secondArchitecture.InitializeAsync());
|
||||
Assert.ThrowsAsync<InvalidOperationException>(async () => await secondArchitecture.InitializeAsync().ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -141,7 +141,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
{
|
||||
if (firstArchitecture is not null && !firstDestroyed)
|
||||
{
|
||||
await firstArchitecture.DestroyAsync();
|
||||
await firstArchitecture.DestroyAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
DeleteDirectoryIfExists(rootPath);
|
||||
@ -203,7 +203,7 @@ public class ArchitectureConfigIntegrationTests
|
||||
var module = CreateModule(rootPath);
|
||||
|
||||
readyArchitecture = new ReadyOnlyArchitecture();
|
||||
await readyArchitecture.InitializeAsync();
|
||||
await readyArchitecture.InitializeAsync().ConfigureAwait(false);
|
||||
readyArchitectureInitialized = true;
|
||||
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => readyArchitecture.InstallModule(module));
|
||||
@ -216,13 +216,13 @@ public class ArchitectureConfigIntegrationTests
|
||||
Assert.That(module.IsInitialized, Is.False);
|
||||
});
|
||||
|
||||
await readyArchitecture.DestroyAsync();
|
||||
await readyArchitecture.DestroyAsync().ConfigureAwait(false);
|
||||
readyArchitectureInitialized = false;
|
||||
readyArchitecture = null;
|
||||
GameContext.Clear();
|
||||
|
||||
retryArchitecture = new ModuleOnlyArchitecture(module);
|
||||
await retryArchitecture.InitializeAsync();
|
||||
await retryArchitecture.InitializeAsync().ConfigureAwait(false);
|
||||
retryArchitectureInitialized = true;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
@ -235,12 +235,12 @@ public class ArchitectureConfigIntegrationTests
|
||||
{
|
||||
if (retryArchitecture is not null && retryArchitectureInitialized)
|
||||
{
|
||||
await retryArchitecture.DestroyAsync();
|
||||
await retryArchitecture.DestroyAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (readyArchitecture is not null && readyArchitectureInitialized)
|
||||
{
|
||||
await readyArchitecture.DestroyAsync();
|
||||
await readyArchitecture.DestroyAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
DeleteDirectoryIfExists(rootPath);
|
||||
|
||||
@ -50,7 +50,7 @@ public class GameConfigBootstrapTests
|
||||
var registry = new ConfigRegistry();
|
||||
using var bootstrap = CreateBootstrap(registry);
|
||||
|
||||
await bootstrap.InitializeAsync();
|
||||
await bootstrap.InitializeAsync().ConfigureAwait(false);
|
||||
|
||||
var monsterTable = registry.GetMonsterTable();
|
||||
|
||||
@ -74,7 +74,7 @@ public class GameConfigBootstrapTests
|
||||
CreateMonsterFiles();
|
||||
|
||||
using var bootstrap = CreateBootstrap();
|
||||
await bootstrap.InitializeAsync();
|
||||
await bootstrap.InitializeAsync().ConfigureAwait(false);
|
||||
|
||||
var reloadTaskSource = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
bootstrap.StartHotReload(
|
||||
@ -95,7 +95,7 @@ public class GameConfigBootstrapTests
|
||||
faction: dungeon
|
||||
""");
|
||||
|
||||
var tableName = await WaitForTaskWithinAsync(reloadTaskSource.Task, TimeSpan.FromSeconds(5));
|
||||
var tableName = await WaitForTaskWithinAsync(reloadTaskSource.Task, TimeSpan.FromSeconds(5)).ConfigureAwait(false);
|
||||
var monsterTable = bootstrap.Registry.GetMonsterTable();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
@ -163,11 +163,11 @@ public class GameConfigBootstrapTests
|
||||
Is.True,
|
||||
"The first initialization attempt did not reach the guarded lifecycle section.");
|
||||
|
||||
var secondCallerException = Assert.ThrowsAsync<InvalidOperationException>(async () => await bootstrap.InitializeAsync());
|
||||
var secondCallerException = Assert.ThrowsAsync<InvalidOperationException>(async () => await bootstrap.InitializeAsync().ConfigureAwait(false));
|
||||
|
||||
continueInitialization.Set();
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await firstInitializeTask);
|
||||
Assert.DoesNotThrowAsync(async () => await firstInitializeTask.ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -202,7 +202,7 @@ public class GameConfigBootstrapTests
|
||||
})
|
||||
});
|
||||
|
||||
var exception = Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await bootstrap.InitializeAsync());
|
||||
var exception = Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await bootstrap.InitializeAsync().ConfigureAwait(false));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -311,12 +311,12 @@ public class GameConfigBootstrapTests
|
||||
/// <returns>任务结果。</returns>
|
||||
private static async Task<T> WaitForTaskWithinAsync<T>(Task<T> task, TimeSpan timeout)
|
||||
{
|
||||
var completedTask = await Task.WhenAny(task, Task.Delay(timeout));
|
||||
var completedTask = await Task.WhenAny(task, Task.Delay(timeout)).ConfigureAwait(false);
|
||||
if (!ReferenceEquals(completedTask, task))
|
||||
{
|
||||
Assert.Fail($"Timed out after {timeout} while waiting for file watcher notification.");
|
||||
}
|
||||
|
||||
return await task;
|
||||
return await task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,7 +522,10 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
/// <param name="content">要写入的 YAML 或 schema 内容。</param>
|
||||
private void CreateConfigFile(string relativePath, string content)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
var directoryPath = Path.GetDirectoryName(filePath);
|
||||
@ -609,7 +612,10 @@ public sealed class YamlConfigLoaderAllOfTests
|
||||
/// <returns>已注册测试表与 schema 路径的加载器。</returns>
|
||||
private YamlConfigLoader CreateMonsterRewardLoader()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_rootPath);
|
||||
if (_rootPath is null)
|
||||
{
|
||||
throw new InvalidOperationException("Root path is not initialized.");
|
||||
}
|
||||
|
||||
return new YamlConfigLoader(_rootPath)
|
||||
.RegisterTable<int, MonsterAllOfConfigStub>(
|
||||
|
||||
@ -271,7 +271,7 @@ public class PersistenceTests
|
||||
continueMigration.Set();
|
||||
|
||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => await loadTask.ConfigureAwait(false));
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save");
|
||||
var persisted = await storage.ReadAsync<TestVersionedSaveData>("saves/slot_1/save").ConfigureAwait(false);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -593,7 +593,7 @@ public class PersistenceTests
|
||||
|
||||
throwingStorage.ThrowOnWrite = true;
|
||||
Assert.ThrowsAsync<InvalidOperationException>(
|
||||
async () => await repository.SaveAsync(primaryLocation, new TestSimpleData { Value = 99 }));
|
||||
async () => await repository.SaveAsync(primaryLocation, new TestSimpleData { Value = 99 }).ConfigureAwait(false));
|
||||
|
||||
var cachedAfterFailure = await repository.LoadAsync<TestSimpleData>(primaryLocation);
|
||||
Assert.That(cachedAfterFailure.Value, Is.EqualTo(1));
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using GameJsonSerializer = GFramework.Game.Serializer.JsonSerializer;
|
||||
|
||||
@ -182,8 +183,8 @@ public sealed class JsonSerializerTests
|
||||
var parts = raw.Split(':');
|
||||
return new CoordinateStub
|
||||
{
|
||||
X = int.Parse(parts[0]),
|
||||
Y = int.Parse(parts[1])
|
||||
X = int.Parse(parts[0], CultureInfo.InvariantCulture),
|
||||
Y = int.Parse(parts[1], CultureInfo.InvariantCulture)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,35 +6,33 @@
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-054`
|
||||
- 当前阶段:`Phase 54`
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-055`
|
||||
- 当前阶段:`Phase 55`
|
||||
- 当前焦点:
|
||||
- `2026-04-24` 本轮继续按 `$gframework-batch-boot 75` 推进,切入 `GFramework.Game.Tests` 的低风险测试 warning,而不进入 `YamlConfigLoaderTests.cs` 等高上下文热点
|
||||
- 已完成 `PersistenceTestUtilities` 的单类型拆分,并在多组 YAML / persistence 测试中补齐 `.ConfigureAwait(false)` 与字段态显式状态检查
|
||||
- `GFramework.Game.Tests` 当前 `Release` build 已从本轮入口观测值 `116 warning(s)` 收敛到 `71 warning(s)`,且本轮 touched files 已不再出现在 warning 输出里
|
||||
- 当前工作树相对 `origin/main` 的累计 diff 已达到 `76` 个文件、`986` 行变更,超过 `$gframework-batch-boot 75` 的主停止阈值;本轮必须在提交后停止继续扩批
|
||||
- `2026-04-24` 本轮先纠正了 batch stop-condition 的计算口径:应使用 `origin/main` 与 `HEAD` 的 merge-base 分支 diff,而不是工作树 diff
|
||||
- 在该正确口径下,`RP-054` 提交后的真实 branch 体积是 `23` 个文件、`603` 行;当前这批提交后的投影体积是 `26` 个文件、`691` 行,仍低于 `$gframework-batch-boot 75`
|
||||
- 本轮已完成 `ArchitectureConfigIntegrationTests`、`GameConfigBootstrapTests`、`JsonSerializerTests` 的小热点清理,并顺手补齐 `YamlConfigLoaderAllOfTests` / `PersistenceTests` 的残余 warning
|
||||
- 当前仍在 `GFramework.Game.Tests` 内推进,但剩余热点已经越来越集中到 `YamlConfigLoaderTests.cs` 与 `GeneratedConfigConsumerIntegrationTests.cs` 这类高上下文文件
|
||||
|
||||
## 当前活跃事实
|
||||
|
||||
- 之前记录的 plain `dotnet build` `0 Warning(s)` 属于增量构建假阴性,不能再作为 warning 检查真值
|
||||
- 本轮直接执行仓库根目录 `dotnet clean` 仍在 `ValidateSolutionConfiguration` 阶段失败,输出未提供具体 error 文本
|
||||
- 本轮直接执行仓库根目录 `dotnet build GFramework.sln -c Release` 成功,并给出 `116 warning(s)` 的当前整仓入口观测值;其中低风险热点主要落在 `GFramework.Game.Tests`
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release` 在本轮收尾验证中为 `71 Warning(s)`、`0 Error(s)`;剩余 warning 已集中在未触碰的 `YamlConfigLoaderTests.cs`、`GeneratedConfigConsumerIntegrationTests.cs`、`GameConfigBootstrapTests.cs`、`ArchitectureConfigIntegrationTests.cs`、`JsonSerializerTests.cs`
|
||||
- 本轮已验证 `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests|FullyQualifiedName~YamlConfigLoaderDependentSchemasTests|FullyQualifiedName~YamlConfigLoaderDependentRequiredTests|FullyQualifiedName~YamlConfigLoaderNegationTests|FullyQualifiedName~YamlConfigLoaderAllOfTests|FullyQualifiedName~YamlConfigLoaderEnumTests|FullyQualifiedName~YamlConfigTextValidatorTests|FullyQualifiedName~YamlConfigSchemaValidatorTests|FullyQualifiedName~PersistenceTests"`,结果为 `Passed: 63`
|
||||
- `PersistenceTestUtilities.cs` 已拆分为 `TestDataLocation.cs`、`TestSaveData.cs`、`TestVersionedSaveData.cs`、`TestSimpleData.cs`、`TestNamedData.cs`,与仓库“一文件一主类型”风格对齐
|
||||
- 仓库根目录 `dotnet clean GFramework.sln -c Release` 仍在 `ValidateSolutionConfiguration` 阶段失败,项目级 `dotnet clean GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release` 也未能稳定提供 clean 基线
|
||||
- 当前整仓最近一次直接观测值仍是 `dotnet build GFramework.sln -c Release` 的 `116 warning(s)`
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release` 已从上一批入口的 `116 warning(s)` 继续收敛到本轮收尾的 `63 warning(s)`
|
||||
- 本轮已验证 `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureConfigIntegrationTests|FullyQualifiedName~GameConfigBootstrapTests|FullyQualifiedName~JsonSerializerTests"`,结果为 `Passed: 19`
|
||||
- `GFramework.Game.Tests` 当前剩余 warning 主要集中在未触碰的 `YamlConfigLoaderTests.cs`、`GeneratedConfigConsumerIntegrationTests.cs`,以及少量未处理的 `GameConfigBootstrapTests` 之外热点
|
||||
|
||||
## 当前风险
|
||||
|
||||
- 如果后续继续依赖增量 `dotnet build`,容易再次把 warning 数量误判为 0
|
||||
- 缓解措施:每轮 warning 检查前先执行 `dotnet clean`,再执行目标 `dotnet build`
|
||||
- 仓库根目录 `dotnet clean` 目前仍然无法给出新的 clean 基线
|
||||
- 缓解措施:若下一轮继续做整仓 warning reduction,先定位 `dotnet clean` 的 solution-level / project-level 失败原因,或明确继续沿用用户确认的 `1193 warning(s)` clean 基线与本轮 direct build 观测值
|
||||
- 仓库根目录与 `GFramework.Game.Tests` 的 `dotnet clean` 目前都无法给出新的 clean 基线
|
||||
- 缓解措施:后续若继续整仓 warning reduction,需要单独定位 clean 失败原因,或明确继续沿用 direct build 观测值作为临时真值
|
||||
- 当前 worktree 仍存在未跟踪的 `.codex` 目录
|
||||
- 缓解措施:提交当前批次时只暂存 analyzer-warning-reduction 相关源码与 `ai-plan` 文件,避免把工作目录辅助文件混入提交
|
||||
- 当前批次已触发 `$gframework-batch-boot 75` 的主停止条件
|
||||
- 缓解措施:本轮提交后停止继续扩批;下一次继续前先评估是否需要基于更新后的 `origin/main` 重新选择基线,或切到新分支 / 新轮次处理剩余 `GFramework.Game.Tests` 热点
|
||||
- `GFramework.Game.Tests` 的剩余 warning 主要集中在大文件与集成测试文件
|
||||
- 缓解措施:后续若继续,优先把 `YamlConfigLoaderTests.cs` 单独作为一个高上下文切片处理,不要和其它 warning family 混批
|
||||
- 下一轮若继续深入 `GFramework.Game.Tests`,很可能需要进入 `YamlConfigLoaderTests.cs` 这种高上下文大文件
|
||||
- 缓解措施:把它单独作为一个明确的新批次处理,不与其它 warning family 混批
|
||||
|
||||
## 活跃文档
|
||||
|
||||
@ -57,11 +55,11 @@
|
||||
- `dotnet clean GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 结果:失败;clean 阶段在 MSBuild 清理路径结束前返回 `0 Warning(s)`、`0 Error(s)`,未输出额外错误文本
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 结果:成功;`71 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests|FullyQualifiedName~YamlConfigLoaderDependentSchemasTests|FullyQualifiedName~YamlConfigLoaderDependentRequiredTests|FullyQualifiedName~YamlConfigLoaderNegationTests|FullyQualifiedName~YamlConfigLoaderAllOfTests|FullyQualifiedName~YamlConfigLoaderEnumTests|FullyQualifiedName~YamlConfigTextValidatorTests|FullyQualifiedName~YamlConfigSchemaValidatorTests|FullyQualifiedName~PersistenceTests"`
|
||||
- 结果:成功;`Passed: 63`、`Failed: 0`
|
||||
- 结果:成功;`63 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureConfigIntegrationTests|FullyQualifiedName~GameConfigBootstrapTests|FullyQualifiedName~JsonSerializerTests"`
|
||||
- 结果:成功;`Passed: 19`、`Failed: 0`
|
||||
|
||||
## 下一步建议
|
||||
|
||||
1. 提交当前 `GFramework.Game.Tests` warning 清理批次与 `RP-054` tracking 更新,然后停止当前 batch loop,因为 branch diff 已达 `76/75`
|
||||
2. 下一轮若继续 warning reduction,应先决定是重新整理 `origin/main` 基线,还是单独开一个高上下文批次处理 `YamlConfigLoaderTests.cs`
|
||||
1. 提交当前 `GFramework.Game.Tests` 小热点批次与 `RP-055` tracking 更新,继续保持只纳入本 topic 相关文件
|
||||
2. 下一轮若继续 warning reduction,应优先决定是否接受进入 `YamlConfigLoaderTests.cs` 的高上下文批次
|
||||
|
||||
@ -2,6 +2,31 @@
|
||||
|
||||
# Analyzer Warning Reduction 追踪
|
||||
|
||||
## 2026-04-24 — RP-055
|
||||
|
||||
### 阶段:修正 stop-condition 口径并继续 `GFramework.Game.Tests` 小热点
|
||||
|
||||
- 触发背景:
|
||||
- `RP-054` 之后复核 batch stop-condition 时,发现之前一度把工作树 diff 错当成了 skill 要求的 branch diff
|
||||
- 按正确口径 `merge-base(origin/main, HEAD)` 计算,`RP-054` 提交后的真实分支体积是 `23` 个文件、`603` 行,因此仍可继续下一批
|
||||
- 当前剩余 warning 里,`ArchitectureConfigIntegrationTests`、`GameConfigBootstrapTests`、`JsonSerializerTests` 属于独立且低风险的小切片
|
||||
- 主线程实施:
|
||||
- 在 `ArchitectureConfigIntegrationTests.cs` 中补齐异步架构初始化 / 销毁和异常断言的 `.ConfigureAwait(false)`
|
||||
- 在 `GameConfigBootstrapTests.cs` 中补齐启动流程、并发初始化断言与 `WaitForTaskWithinAsync` 的 `.ConfigureAwait(false)`
|
||||
- 在 `JsonSerializerTests.cs` 中将坐标解析改为 `CultureInfo.InvariantCulture`
|
||||
- 顺手清理 `YamlConfigLoaderAllOfTests.cs` 与 `PersistenceTests.cs` 中上一批遗漏的字段态状态检查和异步等待 warning
|
||||
- 纠正 active tracking:明确 stop-condition 必须使用 `origin/main...HEAD` 的 merge-base 分支 diff,而不是工作树 diff
|
||||
- 验证里程碑:
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 并行误用 build/test 时:出现 `MSB3026` / `CS2012` 文件占用噪声,不计入代码结论
|
||||
- 串行复验:成功;`63 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureConfigIntegrationTests|FullyQualifiedName~GameConfigBootstrapTests|FullyQualifiedName~JsonSerializerTests"`
|
||||
- 结果:成功;`Passed: 19`、`Failed: 0`
|
||||
- 当前结论:
|
||||
- `GFramework.Game.Tests` 已从上一批收尾时的 `71 warning(s)` 进一步降到 `63 warning(s)`
|
||||
- 这次提交后的分支体积投影为 `26` 个文件、`691` 行,仍低于 `$gframework-batch-boot 75`
|
||||
- 剩余热点越来越集中到 `YamlConfigLoaderTests.cs` 与 `GeneratedConfigConsumerIntegrationTests.cs`,后续继续时应把它们视为高上下文批次
|
||||
|
||||
## 2026-04-24 — RP-054
|
||||
|
||||
### 阶段:`GFramework.Game.Tests` 低风险测试 warning 批次(触发文件数停止阈值)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user