PROJECT_REPORT.md:论文式项目报告(摘要 / 目录 / 7 章 / 参考文献 / 致谢 / 附录 A),
4 张 Mermaid 图同样经真实浏览器渲染验证。所有数字都与证据文件逐个核对过。
.scratch/ci-cd/:本次流水线的全部证据与可重跑脚本
* 阶段报告:依赖安全扫描 / 许可证合规 / 阶段 0 静态分析 / 阶段 3 测试与性能
* 证据:分析器原始输出(修复前 84 条、修复后 80 条)、Pester 详细输出、
性能基线 JSON、黑盒用例结果(阶段 1 的 11 例与阶段 2 回归的 12 例)
* 可重跑:blackbox-tests.ps1 / blackbox-regression.ps1 / perf-baseline.ps1
两条边界必须写在明处,不能含糊:
* **VM 内验证只取到修复前的快照**(Pester 183 项全绿)。随后会话审批策略改为 never,
gsudo 提权被自动拒绝(退出码 999),而 Hyper-V 与 PowerShell Direct 都需要管理员,
于是修复后的三套件在 VM 内**没有跑成**。报告里明确标注了范围,没有把"宿主跑绿了"
说成"VM 也跑绿了"。
* **性能基线是首次建立**,无历史可比,故无退化可判;指标只在同机同宿主下对比,
跨机比数字没有意义。
另外记一笔:静态分析的口径是"仓库自己的门禁"。剩余 80 条全是风格类(0 Error),且逐条
有依据 —— 行长 160 是配置里写明的有意偏离,PSPlaceCloseBrace 等集中在测试夹具字符串内
(改了会改变断言语义)。严格模式的"零容忍"在这里与仓库自身约定相抵,选择尊重仓库约定
并在报告里登记,而不是制造一个横跨 12 个文件的纯排版大 diff。
144 lines
5.8 KiB
JSON
144 lines
5.8 KiB
JSON
{
|
||
"testedAt": "2026-09-28T12:35:02",
|
||
"scope": "文档契约黑盒测试(README 为准)",
|
||
"sandbox": "C:\\Users\\Shuery\\AppData\\Local\\Temp\\baknret-bb-45647a8d",
|
||
"total": 11,
|
||
"passed": 9,
|
||
"failed": 2,
|
||
"fatalOrSevere": 0,
|
||
"cases": [
|
||
{
|
||
"Id": "BB-01",
|
||
"Module": "备份",
|
||
"Title": "文档承诺:备份成功返回 0,并产出 .7z 归档",
|
||
"Priority": "P0",
|
||
"Precondition": "沙盒清单:1 个目录(含排除)+ 1 个不存在的源",
|
||
"Steps": "Backup-Data.ps1(无 -DryRun)",
|
||
"Expected": "退出码 0;Backups\\ 下出现 1 个 .7z;manifest.json 存在",
|
||
"Actual": "退出码=0;归档=1 个(srcdocs_from_C_+Users+Shuery+AppData+Local+Temp+baknret-bb-45647a8d.7z)",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-02",
|
||
"Module": "排除",
|
||
"Title": "文档承诺::- 排除模式把内容挡在归档之外",
|
||
"Priority": "P0",
|
||
"Precondition": "清单里对源目录写了 :- 'nested\\skipme.log'",
|
||
"Steps": "7z l 列出归档内容",
|
||
"Expected": "归档里**没有** skipme.log,但有 a.txt 与 b.txt",
|
||
"Actual": "skipme.log 命中=False;a/b.txt 命中=True",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-03",
|
||
"Module": "干跑",
|
||
"Title": "文档承诺:-DryRun 一个字节都不写(含 manifest.json)",
|
||
"Priority": "P0",
|
||
"Precondition": "已有 1 份归档与 manifest.json",
|
||
"Steps": "记录 SHA256 → 跑 -DryRun → 再记录 SHA256",
|
||
"Expected": "退出码 0;manifest.json 的 SHA256 前后完全一致",
|
||
"Actual": "退出码=0;哈希 6D726A618FD8 → 6D726A618FD8",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-04",
|
||
"Module": "异常流",
|
||
"Title": "文档承诺:源路径不存在记 missing-source,不算失败",
|
||
"Priority": "P1",
|
||
"Precondition": "清单第 2 行指向不存在的目录",
|
||
"Steps": "跑备份后读 manifest.json 的 action 字段",
|
||
"Expected": "该条目 action=missing-source,且整体退出码仍为 0",
|
||
"Actual": "退出码=0;manifest action 分布=backed-up,missing-source",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-05",
|
||
"Module": "干跑",
|
||
"Title": "文档承诺:-Only 只处理匹配的条目",
|
||
"Priority": "P1",
|
||
"Precondition": "清单 2 条:srcdocs(目录)、nonexistent(不存在)",
|
||
"Steps": "Backup-Data.ps1 -DryRun -Only 'srcdocs'",
|
||
"Expected": "退出码 0;输出里不出现未选中的 nonexistent 条目",
|
||
"Actual": "退出码=0;输出提到 nonexistent=False",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-06",
|
||
"Module": "异常流",
|
||
"Title": "边界值:清单文件不存在时的行为",
|
||
"Priority": "P1",
|
||
"Precondition": "传入一个不存在的 -BackupListPath",
|
||
"Steps": "Backup-Data.ps1 -BackupListPath <不存在>",
|
||
"Expected": "明确报错(非 0 退出码)或给出可读提示,**不得静默返回 0**",
|
||
"Actual": "退出码=0;末行=[2026-09-28 12:34:54] [INFO] 模板 BackupList.txt 已创建,请编辑后重试。",
|
||
"Status": "FAIL",
|
||
"Severity": "一般"
|
||
},
|
||
{
|
||
"Id": "BB-07",
|
||
"Module": "兼容",
|
||
"Title": "文档承诺:旧名字 Backup.ps1 是转发垫片,退出码原样传递",
|
||
"Priority": "P1",
|
||
"Precondition": "实现已改名为 Backup-Data.ps1",
|
||
"Steps": "Backup.ps1 -DryRun(旧名字)",
|
||
"Expected": "打印改名提示;退出码与直接调用一致(0)",
|
||
"Actual": "退出码=0;有改名提示=True",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-08",
|
||
"Module": "跨端一致性",
|
||
"Title": "文档承诺:Windows PowerShell 5.1 与 7.x 行为一致",
|
||
"Priority": "P0",
|
||
"Precondition": "同一沙盒、同一清单",
|
||
"Steps": "两个宿主各跑一次 -DryRun,比较退出码",
|
||
"Expected": "两者退出码都是 0(GBK 控制台下的中文输出不崩)",
|
||
"Actual": "7 退出码=0;5.1 退出码=0",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-09",
|
||
"Module": "边界值",
|
||
"Title": "特殊字符:含 & 与 # 的路径(整行引号写法)",
|
||
"Priority": "P2",
|
||
"Precondition": "源目录名含 & 与 #;清单行整体加引号",
|
||
"Steps": "备份该条目",
|
||
"Expected": "退出码 0 且真的产出归档(# 不被当注释吃掉)",
|
||
"Actual": "退出码=0;归档数=1",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-10",
|
||
"Module": "无头",
|
||
"Title": "文档承诺:没有控制台且没给 -InputScript 时报错退出,绝不挂起",
|
||
"Priority": "P0",
|
||
"Precondition": "stdout/stderr 被重定向(等价于计划任务/管道环境)",
|
||
"Steps": "不传参数直接运行 Manage-Backup.ps1,等待最多 60 秒",
|
||
"Expected": "60 秒内退出,退出码 2,并提示\"没有可用的控制台\"",
|
||
"Actual": "60 秒内退出=True;退出码=2;输出片段=û�п��õĿ���̨��Ҳû�и��� -InputScript�������뽻�����档\r\nҪ�ǽ���ִ�У���ָ�����������磺-Action Backup ",
|
||
"Status": "PASS",
|
||
"Severity": ""
|
||
},
|
||
{
|
||
"Id": "BB-11",
|
||
"Module": "审计",
|
||
"Title": "文档承诺:孤儿归档会被点名",
|
||
"Priority": "P1",
|
||
"Precondition": "Backups3\\ 里放一个清单中不存在的 GhostSoftware.7z",
|
||
"Steps": "备份后看输出是否点名",
|
||
"Expected": "输出里出现该孤儿归档名",
|
||
"Actual": "退出码=0;点名=False",
|
||
"Status": "FAIL",
|
||
"Severity": "一般"
|
||
}
|
||
]
|
||
}
|