Skip to content

Commit b6d490a

Browse files
committed
fix(test): 优化 PowerShell 测试热点以降低 host 测试耗时
- 重构 cache.psm1,引入内部 helper(Get-CacheCurrentTime、Get-CacheFiles、Get-CacheFileStatistics)减少重复文件扫描与时间判断 - 重构 Invoke-Benchmark.ps1,新增 Resolve-BenchmarkCatalogItem 与 Invoke-BenchmarkCommand helper,将路由逻辑与执行分离 - 更新相关测试文件(cache.Tests.ps1、Invoke-Benchmark.Tests.ps1、test.Tests.ps1 等),将高成本断言下沉为进程内测试,仅保留最小真实 smoke - 调整模块导入方式(git.Tests.ps1、selection.Tests.ps1),避免整包导入以提升测试速度 - 新增 -NoLogo 参数(Sync-PathFromBash.Tests.ps1)以减少子进程输出 - 新增 brainstorm 与 plan 文档,记录优化目标与实施详情
1 parent cef49aa commit b6d490a

11 files changed

Lines changed: 1365 additions & 416 deletions
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
date: 2026-03-15
3+
topic: pwsh-test-host-priority
4+
---
5+
6+
# PowerShell 测试热点继续收口,优先压 host 到 15s 左右
7+
8+
## What We're Building
9+
这次要收敛的是 2026-03-15 当前这轮 PowerShell 测试继续提速的目标边界,而不是重新讨论测试命令该怎么分层。
10+
11+
现状是:前两轮优化之后,用户体感总耗时约 `38s`,其中测试阶段约 `23s`;最新慢测清单里最明显的共享热点仍然是:
12+
13+
- `psutils/tests/cache.Tests.ps1`
14+
- host `6.59s`
15+
- linux `5.25s`
16+
- `tests/Invoke-Benchmark.Tests.ps1`
17+
- host `5.16s`
18+
- linux `3.87s`
19+
20+
用户希望继续往下压,理想目标是整体进入 `20s` 内,或者至少把 host 测试压到 `15s` 左右。经过本轮澄清后,优先级已经明确:如果两条线不能一次同时打满,先保 host `15s` 左右这条硬线,同时尽量带动 `pnpm test:pwsh:all` 继续下降。
21+
22+
## Why This Approach
23+
当前约束已经把方案空间收得很窄:
24+
25+
- 不接受重新分层,`pnpm test:pwsh:all` 继续保持现在这条完整门禁语义。
26+
- 允许修改生产代码或模块,只要外部行为不变;这意味着可以为测试加 seam,而不是只能在 Pester 文件里“挤牙膏式”压时间。
27+
- 用户已经明确选择了“共享 seam + 保留 1 条真实 smoke”这条路线,而不是只做测试层微调。
28+
29+
在这个前提下,最高收益的点很集中:
30+
31+
- `Invoke-Benchmark.Tests.ps1` 的显著成本主要来自重复拉起真实 `pwsh -NoProfile -File` 子进程;如果不抽 helper,单靠 Pester 技巧很难继续大幅下降。
32+
- `cache.Tests.ps1` 的显著成本主要来自真实文件系统副作用、时间判断与重复清理;如果不在 `cache.psm1` 里增加更可测的边界,也很难继续压。
33+
- 这两个文件合计已经占 host 热点的核心份额,优先处理它们,比再去抠大量亚秒级文件更接近目标。
34+
35+
换句话说,这次不是“再普遍优化一点”,而是聚焦两个共享热点,用生产代码层面的轻量 seam 换取更便宜的测试执行路径。
36+
37+
## Approaches Considered
38+
39+
### Approach 1: 共享 seam + 保留 1 条真实 smoke
40+
`scripts/pwsh/devops/Invoke-Benchmark.ps1``psutils/modules/cache.psm1`,把目录发现、参数路由、时间判断、文件副作用这类高频逻辑拆成可在进程内测试的 helper;`tests/Invoke-Benchmark.Tests.ps1` 保留 1 条真实 CLI smoke,其余优先改成 in-process;`cache.Tests.ps1` 保留真实语义,但减少不必要的真实等待和重复 IO。
41+
42+
**Pros:**
43+
- 最有机会同时打掉 host 侧两个最大热点。
44+
- 不改 `all/full` 的门禁边界。
45+
- 真实 CLI 和真实缓存语义仍保留最小 smoke,不会把风险全推给 mock。
46+
47+
**Cons:**
48+
- 需要改生产代码。
49+
- 需要更仔细地守住外部行为不变。
50+
51+
**Best when:** 不改门禁语义,但要优先冲 host `15s`
52+
53+
### Approach 2: 只改测试文件,不动生产代码
54+
主要通过 `BeforeAll` 复用、合并重复断言、减少临时目录和子进程调用次数来提速。
55+
56+
**Pros:**
57+
- 改动面最小。
58+
- 回归风险最低。
59+
60+
**Cons:**
61+
- 提速上限偏低。
62+
- 很难真正解决 `Invoke-Benchmark` 子进程成本和 `cache` 文件系统成本。
63+
64+
**Best when:** 只想拿一轮保守的小收益。
65+
66+
### Approach 3: 更深的测试友好型重构
67+
进一步模块化 benchmark 调度和 cache 生命周期,引入更明确的 clock / IO seam,让大部分测试转成纯函数或轻量集成。
68+
69+
**Pros:**
70+
- 长期最干净。
71+
- 后续再压时间会更容易。
72+
73+
**Cons:**
74+
- 范围最大。
75+
- 这一轮容易做重。
76+
77+
**Best when:** 接受一轮更完整的结构性重构。
78+
79+
## Recommendation
80+
推荐 **Approach 1: 共享 seam + 保留 1 条真实 smoke**
81+
82+
理由很直接:
83+
84+
- 这是在“不重分层”前提下,仍然最可能把 host 测试往 `15s` 压近的路线。
85+
- 它直接命中当前最贵的两个共享热点,而不是在边缘文件上做低收益优化。
86+
- 它还能顺带改善 `pnpm test:pwsh:all`,因为 `cache``Invoke-Benchmark` 都是双平台热点。
87+
- 相比更深的模块化重构,这条路线的改动面更可控,符合“先打最大热点”的 YAGNI 原则。
88+
89+
## Key Decisions
90+
- `pnpm test:pwsh:all` 的默认完整门禁语义保持不变,不通过重新分层来换时间。
91+
- 本轮优先级是 host 测试先压到 `15s` 左右;整体 `20s` 视为本轮尽量逼近的 stretch target,而不是先于 host 目标的硬门槛。
92+
- 允许改生产代码,只要外部行为不变;因此可以在 `Invoke-Benchmark.ps1``cache.psm1` 中引入测试友好的 seam 或 helper。
93+
- `Invoke-Benchmark.Tests.ps1` 应保留 1 条真实 CLI smoke,其余 catalog / 参数路由 / 选择逻辑优先下沉到 in-process 路径。
94+
- `cache.Tests.ps1` 应继续保留真实缓存语义验证,但要减少重复文件系统成本、真实等待和不必要的清理路径。
95+
- 本轮优化顺序应先打 `cache.Tests.ps1``Invoke-Benchmark.Tests.ps1`,再决定是否继续追后面的亚秒级文件。
96+
97+
## Resolved Questions
98+
- 是否接受重新分层默认门禁?
99+
- 不接受,`test:pwsh:all` 继续保留当前完整门禁语义。
100+
- 如果两条目标不能一次同时达成,先保哪条?
101+
- 先保 host 测试压到 `15s` 左右。
102+
- 是否允许为提速修改生产脚本/模块并加入 seam?
103+
- 允许,只要外部行为不变。
104+
- 在几个候选路线中选哪条?
105+
- 选择 `Approach 1: 共享 seam + 保留 1 条真实 smoke`
106+
107+
## Open Questions
108+
- 暂无。
109+
110+
## Next Steps
111+
-> `/ce:plan`,把 `Invoke-Benchmark``cache` 的 seam 设计、测试下沉范围、验证命令和回归基线拆成可执行计划。

0 commit comments

Comments
 (0)