跳转到内容

测试策略

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-targets --all-features --locked
  • 许可证、来源和安全公告检查
  • Starlight 类型检查和静态构建
  • Criterion 基准目标可编译
  • libFuzzer 目标可编译
  • 发布凭据策略和 MSIX 审计接线冒烟测试

文档 locale 检查不仅要求中文页与英文页一一对应,还会剥离 front matter 后拒绝空 Markdown 正文,避免文件存在但生成页面为空白时仍通过 CI。

当前验证注记:keyboard-form.ps1 的 2026-08-28 fresh full-workflow 已在本机 x64 可访问候选上通过。测试先等待启动归档加载完成并回到首页,Reload 后刷新异步重建的 UIA 根节点,无归档转场使用产品定义的 Ctrl+N 快捷键;结构化证据保存在项目 Stage 4 档案中。该结果只覆盖本机 x64 UI Automation,不替代 Narrator、IME、高对比度、DPI 或正式辅助技术认证。

类型 目标
单元测试 格式识别、路径、安全限制、冲突策略
属性测试 随机路径、文件树和边界值
互操作测试 与参考工具双向创建和解压
安全语料 Zip Slip、炸弹、链接、冲突、损坏和截断数据
模糊测试 持续攻击格式识别和解析入口
性能测试 吞吐、压缩率、峰值内存、启动和大列表
冒烟测试 CLI、桌面启动、安装、升级、文件关联和卸载

固定负向矩阵为全部 18 类受支持格式构造带正确签名或扩展提示、但截断/损坏的最小输入,并要求 List 与完整性校验都返回普通错误而不 panic。它补充而不替代持续 libFuzzer campaign、历史 7z 崩溃夹具和第三方真实语料。

基础冒烟还会向真实 zifile-worker.exe 发送版本化 list 请求,要求最终完整进度快照先于 metadata、Unicode entry 和唯一结束事件;随后对 32 MiB 随机输入启动 7z 创建并发送取消控制消息,验证 Worker 在时限内退出、目标不存在且没有临时文件残留。桌面协议单测覆盖缺少终结事件和逐条条目重建;Windows 实机检查验证桌面可通过 Job Object Worker 打开并校验 7z。

Foundation smoke 还使用实际 Windows CLI 对主要可创建格式执行完整往返:TAR+Zstandard、TAR+XZ、TAR+Bzip2、TAR+LZ4、gzip、Zstandard、XZ、LZMA、Bzip2、LZ4 和 Brotli;每个场景都创建归档、执行完整性校验、解压,并断言 Unicode 文件或单流输出内容。ZIP、TAR+gzip、TAR+LZMA 和 AES 7z 由同一冒烟流程中的独立场景覆盖,因此这组矩阵不是只检查能力表或“文件存在”。

核心往返测试还覆盖“更新现有归档”:ZIP、7z 和全部 TAR 组合都会验证同名普通文件替换、嵌套新文件加入、选中条目删除、删除最后一个文件以及更新后重新解包;RAR 单独验证 RAR 5 创建、密码、列表、完整性校验和选择性解压,CAB 单独验证固定 MSZIP 创建、列表、完整性校验和选择性解压;gzip 等单文件流与 RAR/CAB 则验证更新和重命名的明确错误。更新使用同目录临时工作区,失败或取消不得替换原归档;重复或包含关系的删除路径会先规范化,避免重复重建。

列出和完整性校验分别使用兼容旧入口的 ListOptions 与 TestOptions,为 ZIP、7z、RAR、CAB、TAR 组合和七种压缩流提供统一进度与协作取消。列出阶段按扫描条目推进,单压缩流还按实际解码字节反馈;无法预知总数时两套 UI 显示“正在扫描”,完成后再发布一致的最终总量。完整性校验和解压的内部预检会复用同一进度通道,但在主体阶段开始时重置已扫描计数,避免流式文件在真正写出前错误显示为 100%。Worker 每 100 ms 发送有界进度,并在操作返回后补发最终快照,避免小归档只出现初始 0%;预取消回归要求在解析前返回 Cancelled,各格式往返测试同时验证最终进度不变量。

CAB 文件名收集辅助路径也使用调用方的条目上限并检查协作取消,避免临时名称集合脱离统一的资源边界。

完整性校验在解码普通文件内容的同时计算稳定的小写十六进制 SHA-256;目录和仅列出归档时不生成校验和。结果通过现有 ArchiveEntryInfo/Worker 事件传递,旧版缺少可选字段的事件仍可反序列化。ZIP、7z、TAR 家族、单流、RAR 和 CAB 的回归会验证校验结果与进度完成状态一致,CLI 和两套桌面表格会展示同一值;表格中的复制操作还会验证双语动作文案、原生 Iced 剪贴板接线和可访问 UI 的 Clipboard API 失败回退。

CLI 密码单测覆盖显式 opt-in、CRLF/LF 删除、前后空格保留和缺失/空输入拒绝。基础冒烟还要求 CLI 帮助仅暴露 --password-stdin,并通过标准输入真实创建、校验和解压 AES 7z;固定测试密码不输出到结果。

两套桌面 UI 共用稳定 Worker 错误的双语格式化入口。单测覆盖取消、需要密码、无法识别格式、目标冲突和安全限制,并要求路径或后端诊断细节不被丢弃;未知后端错误保持原文,便于排障。

压缩等级契约单测覆盖各编码器的有效范围、核心层边界钳制和固定等级格式。CLI 单测要求 zifile formats 公开每种格式的区间、fixed 或 none,并在创建前拒绝格式级越界值和固定格式的显式等级,避免命令行输入被核心层静默钳制或忽略。基础冒烟还会启动真实 zifile.exe,核对能力表关键行、ZIP 10 被拒绝、TAR 显式等级被拒绝且省略等级可创建。7z 集成回归分别创建等级 0 与 9 的归档,读取公开的 LZMA2 coder properties 并要求两者不同,从归档元数据证明 UI/CLI 传入的等级确实生效,而不是只验证参数经过 Worker。

任务栏状态映射使用纯单元测试覆盖隐藏、不确定、正常和取消状态;x64 Release/MSIX 构建验证 COM 绑定和 App Execution Alias manifest。任务栏视觉检查与 Narrator/UI Automation 检查仍需在适合的交互式测试环境补证。

共享操作队列单元测试覆盖首项立即启动、后续严格 FIFO、32 项容量边界、满队列不丢失返回载荷、陈旧完成 ID 不推进、清空只影响等待项、等待载荷立即释放,以及 Debug 输出不包含载荷。Iced 与 Dioxus 均编译接入同一调度器;在真实前台回合完成“运行中提交至少两项、取消当前项、后续继续、清空等待项”前,不把路线图条目标为完成。

tests/performance/operation-queue-foreground.ps1 使用 100,000 条目 ZIP 在真实前台会话验证 FIFO、取消当前项、继续下一项、清空等待项和 Worker 回收;它支持默认 Iced 与可访问 Dioxus 候选并同时识别中英文 UI。tests/performance/extraction-cancellation-foreground.ps1 使用确定大小的多条目 ZIP,通过 --extract-here 启动真实解压取消流程,检查 Worker 退出,并确认已提交的文件都是完整条目大小、没有部分输出文件。两者都必须在未被用户占用的交互桌面运行;缺少语义 Document UIA 树或未运行前台会话时,证据保持未完成。

核心测试 active_cancellation_does_not_commit_a_partial_zip_output 在首个解压进度数据块后取消 ZIP 解压,要求返回 Cancelled 且原子目标文件不存在;本地重复五次通过。该单测增强了核心层证据,但不能替代真实桌面队列验收。

创建流程的路径回归会拒绝与来源相同或位于来源目录内部的目标,先解析已存在祖先目录并进行 Windows 大小写无关的路径关系判断,再创建目标父目录;因此不会把临时输出重新遍历为输入,也不会在可恢复错误上留下空目录。

解压目标若已存在且是普通文件,会在创建目录前返回结构化的 DestinationExists,保留原文件内容;这与目录内条目的冲突策略分开验证,避免把“目标本身不是目录”误报为不稳定的底层 I/O 错误。

解压目标本身及每个已有输出父路径都会拒绝符号链接、junction 和 reparse point;回归测试确认链接目标不会收到任何文件,避免宿主目录中的预先存在链接绕过归档路径策略。

创建归档时,如果输出文件已经存在,所有临时文件提交路径都会在最终提交前返回结构化的 DestinationExists,并保留原文件内容;这与解压条目的显式覆盖策略分开,避免在不同操作系统上出现不一致的覆盖或底层重命名错误。

展开比限制使用无溢出的精确乘法比较,而不是整数除法;例如在 1000:1 上限下,2001 字节展开自 2 字节压缩数据会被拒绝,不会因截断为 1000 而放行。

偏好设置回归在临时目录中替换已有配置,确认写入完整的双语语言/主题内容,并确认临时文件在成功提交后清理;Windows 实现使用带 MOVEFILE_WRITE_THROUGH 的替换路径。

单流格式的列出阶段也使用调用方提供的展开比上限;配置为 0 时严格禁止任何解码输出,不会被隐式放宽为至少允许一个压缩字节的输出。gzip 回归覆盖这一边界,避免列表阶段与声明式条目检查产生不同的安全策略。

TAR 及其五种压缩组合在解析每个头部后立即累计声明的条目大小,并在跳过压缩载荷前与展开体积、展开比上限比较;因此列出阶段不会为了读到下一个头部而先解码超出预算的载荷。回归矩阵覆盖 TAR、TAR+gzip、TAR+Zstandard、TAR+XZ、TAR+LZMA 和 TAR+Bzip2。

两套创建 UI 现在也会在保存对话框前拒绝符号链接、junction 和 reparse point 来源,与核心层的链接拒绝策略保持一致;Windows Explorer Shell 菜单也会在状态查询阶段执行相同检查,避免菜单或创建按钮先显示可用、点击后才由 Worker 报错;创建表单以双语恢复提示明确说明链接类来源,并要求用户选择原始文件或文件夹。

Windows 条目冲突键使用 Unicode 小写规则;Windows 专属 ZIP 回归用 Ä.txt 与 ä.txt 验证列表阶段先拒绝大小写变体,避免两个条目在实际文件系统中落到同一路径。

性能门禁需要多轮运行和稳定基线,不能用一次共享 CI 结果直接判定回归。

CI 另外运行 Windows performance job,实际执行 format_detection 与 archive_throughput Criterion 基准,固定 10 个样本并保存文本输出、Criterion 基线和 HTML 数据为 30 天 artifact。Criterion 的相对回归提示需要结合相同机器的历史基线复核;该 job 的成功首先证明基准确实执行且没有运行时失败。

archive_throughput 同时测量 ZIP Deflate、TAR + LZMA-alone 与 TAR + LZ4;后两者使用独立的 1 MiB 样本分别测量创建和校验,确保组合格式也有可重复的吞吐观测。

tests/smoke/contract-policy.ps1 锁定 CLI 的 8 个公开命令、18 个创建格式、18 行 formats 能力矩阵、双语公开契约文档,以及运行时错误码 1 和参数语法错误码 2;默认构建并使用 target/debug/zifile.exe,也可传入 -SkipBuild -ExecutablePath <path> 复用已归档的 CLI 进行验证,避免为纯契约检查保留构建缓存。它在 Windows CI 的 Foundation smoke 后运行,最终 1.0 冻结仍需在发布提交上完成。

共享桌面测试还覆盖拖放分类:有效归档的内容签名优先于扩展名,改名归档仍进入浏览流程;对外层签名相同的改名 TAR+gzip、TAR+Zstandard、TAR+XZ 和 TAR+Bzip2,会在最多 1 MiB 压缩输入与 512 字节解码头的有界探测中识别内层 TAR;已知扩展在探测失败时保留兼容回退,普通文件和归档命名目录不会被误判为可打开归档。 Iced 和 Dioxus 的入口回归同时锁定探测在异步/阻塞线程池路径上执行,防止文件头读取回到 UI 事件线程。

文件对话框回归锁定两套 UI 的打开归档、选择解压目录、添加文件/文件夹和保存归档入口均不在 UI 事件线程直接等待;Iced 使用受控 Tokio 阻塞任务,Dioxus 使用 AsyncFileDialog。活动对话框门禁防止重复点击创建多个原生窗口,取消和完成路径都会释放门禁。

归档浏览回归还要求两套 UI 在当前文件夹为空或搜索无匹配时显示双语空状态,而不是渲染一个看似未加载的空表格;搜索清除动作会保留目录并回到第一页。

打开失败回归会区分密码/加密诊断与损坏、未知格式及普通 I/O 错误:可能需要密码时显示密码输入和专用“解锁”操作;其余失败保留待打开路径并显示普通“重新加载”,便于文件刚写完或临时 I/O 故障后的单次重试。共享组合门禁要求仅在空闲、存在待打开路径且不需要密码时启用普通重试,加载中保持禁用,初始空状态不显示;两套 UI 还会在应用结果前拒绝陈旧 Worker 完成事件,避免旧任务覆盖当前归档或忙碌状态。

密码可见性回归覆盖两套 UI 的默认遮蔽、归档与创建字段接线,以及密码释放时同步恢复遮蔽。可访问候选还锁定三个唯一字段 ID、原生复选框标签、动态 password/text 类型和对应 aria-controls;这些源码与单元测试证据不替代真实屏幕阅读器或前台视觉复验。

创建加密压缩文件时,两套 UI 还会在打开保存对话框前要求两次密码完全一致。共享纯函数回归覆盖双空值、精确匹配、大小写差异和任一字段为空;不匹配门禁始终生效,但内联提示会等用户开始操作确认字段后再出现。可访问候选提供独立标签的确认字段、aria-invalid、警报说明,并让一个显示密码复选框同时控制两个字段。创建请求被接受后会释放两个瞬时值及交互状态,切换到不支持加密的格式时也会一并清除。

加密文件列表的密码输入支持 Enter 提交。默认 UI 通过 Iced 输入提交事件复用现有重新加载路径;可访问候选的纯函数回归要求操作可用、非 IME 组合输入且没有 Ctrl/Alt/Shift/Meta 修饰键,锁定键不影响提交,忙碌状态不会重复排队。

创建页回归还要求默认 Iced 与可访问 Dioxus 对来源添加、移除和清空使用相同的双语状态播报;状态会包含本次变化和剩余总数,不能只更新列表而让辅助技术或用户失去反馈。

归档列表的交互语义回归要求只有目录名称使用可操作的导航按钮,普通文件名称保持为文本,文件和目录的选择统一由每行复选框承担。这样普通文件不会显示成无法点击的伪按钮,也不会暗示不存在的名称操作;目录导航仍保留明确的点击目标。

解压操作区回归要求两套 UI 在重命名、覆盖、跳过和报错选项上方提供可见的双语“文件冲突策略”字段名。默认 Iced 使用同一列中的文本标签,可访问 Dioxus 使用原生 label 包裹下拉框;不能只依赖选项内容或仅辅助技术可见的名称说明字段职责。

默认 Iced 的归档密码和搜索字段还必须保留持久可见的双语标签,不能只使用输入框 placeholder;用户输入内容后,字段用途仍应可见。回归同时锁定搜索框 ID、清除动作以及原有密码遮蔽接线,确保布局调整不破坏 Ctrl+F 聚焦、搜索清除或密码可见性行为。可访问 Dioxus 已使用原生标签,继续保持该语义基线。

归档标题的共享大小摘要会同时显示展开大小、压缩后大小和相对比例。单测覆盖正常缩小、压缩后反而增大及空归档:缩小时使用“缩小/smaller”,增大时使用“增大/larger”,不能显示负节省率;展开大小为零时省略没有意义的百分比。两套 UI 的正常和忙碌归档标题都必须传入真实 total_size 与 compressed_size。

关于页外链回归要求两套 UI 都提供项目主页、当前语言文档和当前语言隐私政策三个可操作入口。共享层只接受编译期 OfficialLink 枚举,五个实际地址必须使用 HTTPS 且只能落在项目 GitHub 或 GitHub Pages 路径,不能把任意用户字符串传给系统协议启动器;Windows 使用 ShellExecuteW 调用默认浏览器,启动成功或失败都会更新应用状态区。

保存路径回归要求两个桌面端在用户省略扩展名时补上所选格式的规范后缀,并保留用户明确输入的其他后缀;复合格式例如 TAR + gzip 必须生成完整的 .tar.gz,不能只生成 .gz。

tests/reproducibility/windows-build.ps1 在两个全新目标目录使用固定 Rust 1.93.0、锁文件、单作业构建与 MSVC /Brepro,比较默认桌面、可访问候选、CLI、Worker 和 Explorer DLL。云端 32813453959 在新工具链上得到双架构各 4/5;schema v2 运行 32822543635 进一步确认默认 Iced EXE 的 .rdata 首差异是 glutin_wgl_sys 生成绑定内嵌的 build-a/build-b target 路径。脚本现用 CARGO_ENCODED_RUSTFLAGS 与 --remap-path-prefix 把两个根映射到同一虚拟路径;修复后 32826187552 的 x64/ARM64 都达到 5/5 且 reproducible=true。

Windows CI 使用 PowerShell Compress-Archive/Expand-Archive 和系统 tar.exe,分别对 ZIP、tar.gz、tar.lzma 与 7z 执行双向互操作;其中 tar.exe --lzma 验证 LZMA-alone 组合格式。参考工具创建的包由 ZiFile 校验和解压,ZiFile 创建的包由参考工具解压并逐文件核对;ZIP、tar.gz 与 7z 场景包含 Unicode 路径,tar.lzma 反向场景同时核对 ASCII 文件内容以避免把 Windows 参考工具的代码页差异误当作 ZiFile 结果。每次运行上传不含用户数据的结构化证据。

新增的官方 7-Zip 语料门禁使用 GitHub Windows Runner 上的 7z.exe,覆盖 Copy、LZMA、LZMA2+BCJ、Deflate、BZip2、PPMd,以及带文件名加密的 LZMA2+AES;反向还要求官方 7-Zip 校验并解压 ZiFile 创建的普通与 AES 归档。所有场景逐文件比较 SHA-256,并上传不含密码的 JSON 证据。CI 32836336921 使用 7-Zip 26.02 完成 9/9 场景,证据 JSON SHA-256 为 06278BB8B96AB683A3C117BA5E30F1B4AB1CF89F1BBF01E72BAC0CC26B49DB14。

RAR 门禁从固定的 rars 源码提交 7d8f9386ef777a2415da34fe1db193d8471ff7d0 下载六个夹具,使用硬编码 SHA-256 验证来源后,逐文件比较 ZiFile 与 7-Zip 的解压树。覆盖 RAR 1.3、1.54 多文件、RAR 3 PPMd、RAR 5 压缩与 E8E9 过滤,以及 WinRAR 7.21 加密头/Quick Open;另有三个链接/重定向夹具必须在无输出的情况下拒绝。新增的本地创建回归会由 ZiFile CLI 生成普通和加密 RAR 5,再由 7-Zip 24.09 测试并解压核对。CI 32853686537 完成全部六个有效场景和三个拒绝场景,证据 JSON SHA-256 为 4C52D0240B911609C7DDB0CACB2E484F56C8F886E216347603B228261C4EE8EF。RAR 1.3 因现代 7-Zip 不再读取,改与同一固定上游提交中的已知正确解压树逐文件核对,其余五种有效归档继续与 7-Zip 26.02 交叉验证。

CAB 互操作门禁在 Windows Runner 使用系统 makecab.exe 生成 MSZIP 与 LZX Cabinet,再要求 ZiFile 完成签名识别、浏览、校验和解压,并与系统 expand.exe 的输出比较 SHA-256;同时由 ZiFile 创建固定 MSZIP Cabinet,再要求 expand.exe 成功解压。None 压缩由 Rust 集成夹具覆盖;Quantum 与跨 Cabinet 集合明确不支持。每次 CI 上传不含用户数据的结构化 JSON 证据。

CAB 解码阶段负向回归保留合法元数据并翻转首个 CFDATA 压缩字节,先证明列表仍能读取单个条目,再要求完整性校验失败、选择性解压报错且目标目录为空。该检查证明损坏负载不会越过临时文件提交边界,不把只测损坏头误当成解码器覆盖。

修改时间测试先为源文件和目录设置确定时间,创建 ZIP、7z、RAR 5 与 TAR 家族归档,再要求列表元数据和解压后的文件/目录均保留预期值;独立创建的 RAR 5 与 CAB 夹具继续覆盖读取 Provider。协议测试会反序列化没有可选时间字段的旧版 archive_entry 事件,两套桌面程序还共用格式化测试,明确区分 UTC 与归档格式未保存时区的时间。

每次 CI 会编译 libFuzzer 目标;每周定时工作流对路径策略、格式识别和归档解析器各运行 180 秒有界 fuzz,失败时保留崩溃产物 14 天。归档目标用带格式签名的变异输入覆盖 ZIP、7z、RAR、CAB、七个 TAR 格式和七种单流格式,限制输入为 256 KiB、RSS 为 2 GiB、单输入为 10 秒;目标内部还使用 256 条目、4 MiB 展开量、64 倍压缩比和 32 层路径的严格限制。Windows/MSVC 本地 cargo-fuzz 因 sevenz-rust2 DLL 与 libFuzzer 入口点参数冲突无法链接,Rust 编译检查可通过;动态 campaign 以 Linux GNU 定时工作流为验收环境。损坏、截断、炸弹及更多 libarchive 变体仍需继续扩展。

首轮归档解析器 campaign 32733658052 在约 569,000 次执行后发现 292 字节输入可令 sevenz-rust2 0.20.2 的文件数量分配触发 capacity overflow。第二轮 campaign 32803785688 又发现 173 字节输入可触发 ASan 超大内存分配;这类 OOM 不能由 catch_unwind 可靠隔离。两份输入均已转为永久集成测试和 fuzz 启动重放夹具。项目因此升级到 Rust 1.93.0 与带有元数据计数边界修复的 sevenz-rust2 0.22.0;Provider 的 panic 边界继续作为纵深防御。升级后的定向 campaign 32813469578 强制重放两份样本,并在 181 秒内继续执行 498,937 次、峰值 RSS 370 MiB,未产生新崩溃产物。

libfuzzer-sys 默认 panic hook 会在 unwind 前 abort,绕过 Provider 的错误边界。归档 fuzz 目标只在自身进程初始化时移除这个 hook;libFuzzer 外层仍会令任何逃出 ZiFile 的 panic 失败。目标启动时必定重放上述固定样本,防止新 campaign 因随机语料未再次命中而产生假通过。

当前 8 MiB 可压缩语料在本地 Windows x64 的一次基线中,ZIP 创建约为 262–275 MiB/s,完整性校验约为 3.04–3.15 GiB/s。该结果只用于建立初始量级,不作为跨机器 CI 阈值。

RAR 校验基准使用确定性的 8 MiB RAR 5 method-3 归档,并加入低频伪随机噪声,在保留压缩工作的同时不超过默认 1000:1 膨胀保护。首次本地 Windows x64 基线为 58.12–64.49 ms,即 124.06–137.65 MiB/s;它只用于同机回归,不是通用性能承诺。最初的高度周期性夹具被安全比率按设计拒绝,没有为了跑分绕过该保护。

桌面列表回归测试使用 100,000 个模拟条目,断言搜索结果正确且每次只构造最多 500 个可见行。默认 Iced 与 Dioxus 候选共用 entry_view 实现;运行 cargo bench -p zifile-desktop --bench entry_browser --locked 可复测。2026-08-24 的 Windows x64 基线中,选择性计数为 16.90–17.62 ms(5.68–5.92 M 条/秒),收集有界页为 15.46–15.96 ms(6.27–6.47 M 条/秒)。Windows 实机还以 100,000 个空条目的真实 ZIP 通过隔离 Worker 打开:UI Automation 报告 100,000 项和 200 页,但表格仅暴露当前 500 行;搜索 99999 精确定位末项,搜索 000 形成 3 页并可导航到第 3 页。

排序回归覆盖目录优先、升降序、缺失修改时间末尾、切换后回到第一页和 500 行上限。Criterion 另把全部 100,000 条按名称降序后收集一页;本机 Windows x64 初始结果为 13.96–15.32 ms(6.53–7.17 M 条/秒)。表头辅助测试要求可见方向箭头与 Dioxus aria-sort 状态一致。

目录浏览回归覆盖显式与隐式目录、根目录和嵌套层的直接子项、可导航面包屑、跨目录搜索,以及进入目录后清空搜索并回到第一页。10 万条目夹具在根层只合成一个目录,进入后无论排序方向都只收集当前 500 行。本机 Windows x64 初始基线中,扫描 10 万路径并合成根目录为 18.60–19.44 ms,进入目录后按名称降序并收集 500 行为 38.04–38.74 ms。

目录选择回归覆盖一次扫描得到每个直接子目录的全选/部分/未选计数、只增删目标目录后代、空目录禁用语义,以及文件与隐式目录同路径时目录行优先。Dioxus 源码门禁要求 mixed 状态、双语已选/总数标签和带页内序号的确定性行键。本机 Windows x64 对 10 万条目、半数已选集合的一次根目录聚合为 30.97–32.75 ms。

tests/performance/archive-browser-baseline.ps1 会确定性生成并在结束后删除 100,000 条目 ZIP,启动匹配的优化版候选和 Worker,使用 UI Automation 等待条目数与页码、滚动到 50%、翻到下一页,并以 25 ms 间隔采样根进程及后代在同一采样时刻的内存。五轮正式基线的窗口启动中位数/p95 为 258.07/308.54 ms,首个归档内容为 3373.80/3668.80 ms,50% 滚动为 195.16/246.34 ms,下一页为 805.87/1143.66 ms;同时刻整树工作集/私有内存最大值为 669.18/455.71 MiB,最多 9 个进程。首内容、滚动和翻页数据包含 UI Automation 观察开销,只用于同机回归,不作为用户可感知延迟的纯应用内测量。

tests/performance/archive-load-cancellation.ps1 使用相同的确定性 100,000 条目 ZIP,在候选界面暴露已启用的取消按钮后立即调用,要求最终 live status 为取消错误、不得出现成功打开状态、对应 Worker 必须退出,并在结束时关闭测试实例和删除临时 ZIP。最终五轮基线的取消完成中位数/p95 为 930.78/1088.73 ms;五轮确认时 Worker 数均为 0。该计时从 UI Automation 调用取消开始,到界面收到 Worker 的最终取消结果为止。

tests/accessibility/keyboard-form.ps1 从候选原生窗口根开始发送真实 Tab/Shift+Tab/Enter 和表单按键,并通过 UI Automation 读取 WebView2 内部焦点。它验证首页→归档→创建→主题→语言顺序、反向导航、归档/创建页激活、创建页 disabled 按钮不获得焦点、格式选择为 7z、压缩等级 6→7→6、密码键入后用 Ctrl+A/Backspace 清空,以及两个来源按钮可达。默认流程还创建两个条目的 ZIP,验证归档列表、完整性校验、归档密码框的局部 Ctrl+A、Reload、搜索提交与局部 Ctrl+A、归档全选/清空、冲突策略、单页分页禁用和解压按钮状态;-SkipArchiveWorkflow 仅用于隔离旧的创建表单回归。固定测试密码只在进程内使用,JSON 不记录其值。脚本在每次发送前要求前台原生句柄精确属于本次 ZiFile;正向和反向导航若因窗口焦点同步仍停留在当前控件,只允许有限重发,随后仍要求精确值和下一个控件;用户切换到其他窗口时立即失败并在 finally 中关闭测试实例。默认持久化语言下,Windows x64 已有完整独立前台归档工作流通过证据;-ToggleLanguageBeforeTest -SkipArchiveWorkflow 另已验证切换到另一语言后的创建页键盘流程。原始 JSON 见项目档案;这些证据仍不替代 Narrator、IME、高对比度、DPI 和正式辅助技术认证。

可访问候选会在对应语义控件上公开实际处理的 Ctrl+O、Ctrl+N、F1、Escape 和归档区域 Ctrl+A,源码回归同时锁定处理器与 aria-keyshortcuts 元数据;这证明接线一致,不替代屏幕阅读器的真实朗读验证。

根级键盘处理器只在存在活动取消令牌时接管并阻止 Escape 默认行为;空闲状态返回未处理,使原生控件保留关闭或退出交互。取消函数本身也在令牌缺失时保持无操作,不写入虚假的“正在取消”状态。

快捷键匹配会忽略 Caps Lock、Num Lock 等锁定状态,但要求其他修饰键与公开契约精确一致;因此 Ctrl+Shift+N、Alt+F1 和 Ctrl+Shift+A 不会被降级解释为 Ctrl+N、F1 或 Ctrl+A。回归覆盖正向组合、锁定键兼容以及 Shift/Alt 负向组合。

默认 Iced 桌面的 Ctrl+O、Ctrl+N、归档区域 Ctrl+A、F1 和 Escape 同样遵循功能修饰键精确匹配。Iced 修饰键类型只包含 Shift、Control、Alt 与 Logo,因此无修饰命令要求 NONE,Control 命令要求精确等于 CTRL;纯事件映射回归同时覆盖正向和额外修饰键组合。

可访问候选在首页、归档、创建和关于页之间切换时,会把焦点移到稳定的主内容区域,并用当前页面标题标记该区域。该 effect 以页面身份为门禁,因此进度轮询、队列更新、筛选、选择等同页重绘不会抢走焦点。源码与单元回归锁定页面到标题的映射及焦点触发接线;真实 Narrator 与前台键盘验证仍然必须补充。

可访问候选的普通深色/浅色主题使用双层焦点环:外层按主题选择亮色或深色,内层使用反差色,从而同时覆盖正文表面和青色激活控件;Windows 强制颜色模式改用 Highlight 与 Canvas。Rust 源码回归锁定这三个主题分支和双层接线,但真实可见焦点仍需前台键盘与高对比度回合确认。

tests/performance/operation-queue-foreground.ps1 默认生成 10 万个、每项 1 KiB 的确定性 ZIP 条目,在真实窗口中提交三次完整性校验,并验证取消当前、下一项启动、清空等待队列与 Worker 回收;-EntrySizeBytes 可在受控范围内调整夹具工作量。为避免真实磁盘速度让排队窗口变得偶然,脚本默认通过仅测试用的 ZIFILE_TEST_WORKER_DELAY_MS 给每个 Worker 操作增加 10 秒启动窗口,-WorkerDelayMilliseconds 可在 0 到 10 秒内调整,延迟期间仍监听取消,生产默认值为关闭。脚本用独立的 3 秒有界窗口激活重试证明 ZiFile 原生句柄正是 Windows 前台窗口;无法取得前台资格时拒绝运行,不能把后台 UIA 调用记为真实前台证据。等待文案超时时会附带最多 500 个字符的最后可见 Document 文本;按钮等待超时还会附带最多 32 个按钮的名称与 IsEnabled 状态,且仍在 finally 中关闭进程并删除临时夹具。

tests/smoke/packaging-policy.ps1 在每次 Windows CI 中动态解析当前三十三个发行、语料与仓库政策 PowerShell 脚本,并验证缺失/部分 Partner Center Identity、非法 Name/X.500 Publisher、缺失云签名输入、非法 provider、开发 Identity、未签名 OID Publisher、无效签名产物和未完成的 1.0 就绪清单都会被拒绝,形式正确的输入及 11/11 带证据就绪夹具会被接受;它还要求签后审计、仅签后发布、最小权限、签名超时/并发控制、轮换/应急停止/吊销运维手册,以及版本、发布说明、贡献者、安全和发布就绪门禁均接入 CI。所有 CI、文档部署、SBOM 和 GitHub Release 发布 Job 都有按工作负载设置的硬超时,并由 Job 作用域检查防止误命中同文件其他上限。双架构可复现构建另受 120 分钟硬超时、同分支旧任务取消、矩阵独立结论和失败证据保留约束保护;前台队列脚本的真实窗口所有权与有界诊断也受防退化检查。真实账号、云 HSM 签名和 x64/ARM64 包内容审计不能由策略冒烟替代。

Explorer Shell 的策略检查要求 zifile-shell 复用核心格式识别和能力注册表,并要求解压项目是实际文件;它拒绝重新出现的独立后缀白名单,从源头防止核心格式、文件关联和右键菜单支持范围发生漂移。创建页共享预检还覆盖来源在选择后消失的情况,避免在保存对话框之后才暴露可恢复的输入错误。

tests/smoke/store-listing.ps1 验证简体中文和英文 Store JSON 都满足 Partner Center 的描述、短描述、功能、关键词、系统要求、许可与 HTTPS URL 限制,并要求两份可读文档逐段、逐功能包含结构化 JSON 的权威文案。负向样本证明超长功能、过多关键词及描述中的 URL 会被拒绝。该门禁验证文字材料,不替代截图、年龄分级、正式 Identity 或认证。

同一冒烟还验证截图原子导入:动态生成八张合格 PNG,要求完整采集元数据并从独立目录导入,随后再次运行正式清单验证器;缺少元数据、低分辨率、重复内容和覆盖已有素材都会失败。临时素材最终清理,不会进入正式目录。

tests/helpers/msix-repair 是测试专用的 C# 控制台辅助程序,主产品仍以 Rust 实现。CI 以锁定的 Windows App SDK 1.8 依赖编译,并由不加载 Windows App SDK 的 PowerShell 监护脚本启动无副作用 --probe;因此即使 App SDK 在 helper 入口前阻塞,监护脚本仍会在 15 秒后直接终止该进程,工作流另有 2 分钟外层上限。Runner 不返回时明确记录查询未完成/不支持,不会一直挂起或伪报 Repair 通过;1 秒阻塞夹具持续验证这条硬超时路径。可信包生命周期支持 Repair 时,在包 LocalState 写入随机哨兵,调用 RepairPackageAsync 后要求内容不变,再要求 Reset-AppxPackage 删除哨兵;不支持时证据明确记为 unsupported。

tests/smoke/wack-readiness.ps1 用不签名开发包夹具证明 readiness 会报告 WACK 缺失、签名无效、Partner Center Identity/Publisher/Publisher Display Name 三项不匹配、未签名 Publisher、最低系统版本错误和包/审计哈希不一致,并验证 -RequireReady 失败时仍保存结构化证据。该测试不运行 WACK,也不替代正式签名候选的认证报告。

tests/performance/desktop-baseline.ps1 对优化后的两个桌面程序各启动五次,计时到原生窗口可响应,并在 1.5 秒稳定期后汇总根进程与后代进程内存。参考机器为 Windows 11 build 26200、i9-14900HX:Iced 启动中位数 668.79 ms、工作集 225.87 MiB、私有内存 265.05 MiB;Dioxus/WebView2 候选分别为 294.25 ms、405.91 MiB、206.62 MiB。首轮冷启动包含在 p95 中(Iced 1785.51 ms、候选 644.20 ms)。工作集与私有内存口径不同,该数据是同机回归基线,不代表完整内容就绪、真实十万项归档的精确首屏/滚动延迟或跨机器门禁。