Skip to content

源码测试与生成物地图

梳理 Codex 的单元测试、集成测试、fixture、snapshot、协议生成物以及 Cargo 与 Bazel 验证链路,明确不同改动应由什么测试和生成物支撑。

基于rust-v0.150.0
CodexRustTestingCodegen

源码测试与生成物地图 ​

本文讨论 Codex 仓库中的测试资产,而不只有 tests/。一个行为可能由实现文件旁的单元测试、共享 harness 驱动的 集成测试、磁盘 fixture、insta snapshot、提交到仓库的 JSON/TypeScript schema,以及 Cargo 与 Bazel 两套构建入口共同约束。

这几类文件的维护方式不同:fixture 往往是人工设计的输入和预期状态;snapshot 是测试运行产生、 但必须人工审阅后接受的预期输出;schema 是 Rust 类型的派生产物,应由生成器整体覆盖;target/、 nextest archive 和 JUnit 报告则是一次构建的临时结果,不应提交。把它们都叫“测试文件”会失去最 重要的所有权信息。

本文先回答三个问题:测试逻辑在哪里、测试依赖什么资产、源类型变化后哪些生成物必须同步更新。

本文是一张测试选择地图,不用文件数量代替覆盖率。找到与改动边界匹配的 harness、fixture 或 generator 后,应停止横向清点,进入文末链接的行为专题和具体测试;文件数量只用于发现 资产分布与版本漂移。

1. 四类仓库资产 ​

资产权威来源是否提交正确修改方式漂移如何暴露
测试代码Rust/TypeScript/Python 测试逻辑是人工编写测试编译或断言失败
fixture人工构造的输入、证书、JSON、预期目录是按场景编辑行为测试失败
snapshot测试表达式渲染出的预期文本/UI是运行测试,审阅 .snap.new 后接受insta snapshot mismatch
schema / generated sourceRust 类型、proto 或导出注册表是运行指定生成命令fixture-match test 或 clean-worktree 检查失败
构建与测试产物当前源码和工具链否由 Cargo/Bazel/CI 重建不参与源码 diff

这个分类的判断标准是“谁拥有语义”。例如 config.schema.json 虽然是 JSON 文件,却不应被当成手写 配置文档;它的语义来自 ConfigToml 与 schemars 约束。相反,apply-patch 场景中的 patch.txt 和 expected/ 是测试作者有意设计的规范案例,不能由当前实现反向生成,否则实现错误会 同时污染预期结果。

图中只有 snapshot 接受需要“测试结果 → 人工审阅 → 仓库预期”这条反向边。schema 不走这条路: 它应由源类型确定性生成,再通过 diff 审阅 API 变化。

2. 测试目录 ​

当前 codex-rs 的主要测试布局可以压缩为下面这棵树:

text
codex-rs/
├── <crate>/src/
│   ├── *.rs                         # 实现旁的 #[cfg(test)] 单元测试
│   ├── *_tests.rs                   # 显式 path 引入的专用测试模块
│   └── snapshots/*.snap             # 模块级 insta 预期输出
├── <crate>/tests/
│   ├── all.rs                       # 部分 crate 的集成测试聚合入口
│   ├── suite/*.rs                   # 按行为主题拆分的集成场景
│   ├── common/                      # 该产品的共享 harness/test-support crate
│   └── fixtures/                    # 磁盘输入与预期状态
├── core/tests/
│   ├── all.rs                       # Core 集成测试入口
│   ├── suite/*.rs                   # Turn、工具、审批、恢复、MCP 等端到端场景
│   └── common/                      # core-test-support
├── app-server/tests/
│   ├── suite/*.rs                   # 面向公共 JSON-RPC 的集成场景
│   └── common/                      # app-test-support
├── test-binary-support/             # 测试二进制 arg0/别名装配
├── utils/cargo-bin/                 # Cargo 与 Bazel 的 binary/resource 定位桥
└── .config/nextest.toml             # 并发、重试、慢测试和测试组策略

在当前版本仓库中,可以统计到约 1138 个包含 #[cfg(test)] 或 mod tests 的 Rust 文件、300 个 tests/suite/*.rs 文件、97 个 fixture 文件和 759 个 .snap。数量只能说明验证面很大,不能代替 覆盖判断:TUI 一项就拥有 705 个 snapshot,而一个关键 Core 状态转换可能只需要一个结构化集成测试。

2.1 局部不变量 ​

实现文件旁的测试适合纯函数、解析器、序列化和局部状态机。仓库当前规则要求新增测试模块优先放到 描述性 sibling 文件,再显式挂回实现模块:

源码位置:codex-rs/skills/src/parser.rs :: sibling test module

rust
// 测试实现移到同目录文件,生产模块只保留显式挂载点。
#[cfg(test)]
#[path = "parser_tests.rs"]
mod tests;

这样实现文件不会随着测试膨胀,也能从文件名直接定位测试主题。该规则不要求机械迁移历史内联测试。 断言优先比较完整对象,并使用 pretty_assertions::assert_eq 获得可读 diff;不建议为静态常量编写 没有行为价值的测试。

2.2 Agent进程边界 ​

涉及 agent 逻辑时,仓库规则优先要求 Core 集成测试。core/tests/all.rs 本身只有聚合职责:

源码位置:codex-rs/core/tests/all.rs :: integration test root

rust
// 聚合入口只公开公共错误类型并挂载 suite,不承载具体测试场景。
#![allow(clippy::expect_used)]

pub use codex_protocol::error;

mod suite;

suite/mod.rs 再挂载按主题拆分的文件。这样审批、工具执行、context compaction、resume、MCP、 multi-agent 和网络策略等场景共享一个明确的测试入口,同时仍能按模块维护。

Core harness 的核心是 core-test-support:

  • test_codex 创建隔离的 CODEX_HOME、配置、认证、模型 server 与 session;
  • responses 用 wiremock 伪造 Responses API 和 SSE 事件流;
  • ResponseMock 保存收到的请求,允许按完整结构检查模型输入和 tool output;
  • wait_for_event 等待 Core 事件,而不是在测试中随意 sleep;
  • process、Hook、App、zsh fork 和 remote environment helper 复用真实边界。

下面的类图展示 Core 集成测试 harness 的主要 owner。builder 负责装配,harness 同时持有 mock server 和可操作的 TestCodex,ResponseMock 则独立保存收到的模型请求。

测试不是直接拼装一个私有 Session:TestCodex 仍通过 CodexThread 提交 Op 和等待 Event,mock 只 替换模型边界,因此能覆盖真实 Turn 与工具循环。

典型测试不是直接调用某个私有函数,而是给 mock server 安装一段模型事件,向 Codex 提交 Op::UserTurn,再同时检查外发 request 与回传 event:

源码位置:codex-rs/core/tests/common/responses.rs :: mount_sse_once usage

rust
// 先安装确定的模型事件流,再通过真实 Core submission 驱动工具续轮。
let mock = responses::mount_sse_once(
    &server,
    responses::sse(vec![
        responses::ev_response_created("resp-1"),
        responses::ev_function_call(
            call_id,
            "shell",
            &serde_json::to_string(&args)?,
        ),
        responses::ev_completed("resp-1"),
    ]),
)
.await;

codex.submit(Op::UserTurn { /* ... */ }).await?;
let request = mock.single_request();

源码位置:codex-rs/core/tests/common/responses.rs 与 test_codex.rs。这类测试能同时覆盖模型协议、 Turn 驱动、工具路由和 history 回灌,代价是进程和异步资源更重。

App Server 使用独立的 app-test-support,测试从公共 JSON-RPC 方法进入,而不是绕过 server 直接 调用 Core。默认 builder 会准备可跨 app OS 与 exec OS 的环境;这对 connected app-server 与 exec-server 分居不同系统的场景尤其重要。

2.3 CLI二进制测试 ​

assert_cmd::Command::cargo_bin 只理解 Cargo 的测试布局,Bazel 则把二进制和资源放在 runfiles。 Codex 用 codex-utils-cargo-bin 统一两种解析方式:

源码位置:codex-rs/utils/cargo-bin/src/lib.rs :: cargo_bin

rust
// 优先读取构建系统注入的 binary 位置,只有缺失时才走 Cargo fallback。
use std::path::PathBuf;

pub fn cargo_bin(name: &str) -> Result<PathBuf, CargoBinError> {
    let env_keys = cargo_bin_env_keys(name);
    for key in &env_keys {
        if let Some(value) = std::env::var_os(key) {
            return resolve_bin_from_env(key, value);
        }
    }
}

resolve_bin_from_env() 在 Bazel 环境通过 runfiles::rlocation 解析;没有环境变量时才进入 assert_cmd 的 Cargo fallback。真实实现位于 codex-rs/utils/cargo-bin/src/lib.rs::cargo_bin。 资源文件则使用 find_resource!:Cargo 下从 CARGO_MANIFEST_DIR 查找,Bazel 下从 BAZEL_PACKAGE 与 runfiles manifest 查找。测试若直接拼 target/debug/codex 或依赖当前工作目录,通常只能在一种构建系统中 通过。

test-binary-support 解决另一类问题:同一个测试二进制可以按 argv[0] 装配 Codex 的多调用别名, 并在测试线程启动前建立临时 CODEX_HOME。这让集成测试可以启动接近真实交付形态的 helper,而不用 为每条路径复制一个测试程序。

3. Fixture ​

fixture 的共同点是测试先读取它,再驱动实现;内容不应由本次被测实现自动推导。仓库中的典型类别 如下:

目录内容验证目标
apply-patch/tests/fixtures/scenarios/input/、patch.txt、expected/patch 后文件树必须精确匹配
tools/tests/fixtures/json_schema_policy/各类外部工具 JSON Schemaschema 清洗、大小和安全 policy
http-client/tests/fixtures/CA 与 intermediate PEMTLS trust 与证书链
backend-client/tests/fixtures/task details JSON后端响应反序列化与 diff/error
tui/tests/fixtures/oss-story.jsonlrollout/event 故事流TUI replay 和渲染
exec/tests/fixtures/模型最终输出文本apply-patch/exec 行为

apply-patch 的场景目录最接近可执行规范:测试先复制 input/ 到临时目录,应用 patch.txt,然后递归 快照最终文件树并与 expected/ 深比较。每个场景目录只表达一个操作或失败语义,因此同一套 fixture 可以被不同语言或平台的实现复用。

Fixture 失败时,第一反应不应是覆盖 expected/。应先判断变化来自规范调整、测试输入不完整,还是 实现回归。只有前两种情况才有理由修改 fixture。

4. Snapshot契约 ​

insta snapshot 主要集中在 TUI,因为终端布局由多个 span、换行、宽度、状态和事件共同决定,逐字段 断言难以展示最终用户看到的画面。一个 .snap 文件同时记录源测试、表达式和规范化后的输出:

text
---
source: tui/src/chatwidget/tests/exec_flow.rs
expression: terminal.backend().vt100().screen().contents()
---
  Would you like to run the following command?
  ...

测试 mismatch 会留下 .snap.new。正确流程分三步:

  1. 运行相关测试,例如 just test -p codex-tui;
  2. 用 cargo insta pending-snapshots 或直接阅读 .snap.new 检查视觉变化;
  3. 只在确认所有变化都符合预期后运行 cargo insta accept -p codex-tui。

cargo insta accept 不是修复命令,而是批准新的用户可见契约。仓库规则要求所有 UI 或文本输出变更 增加或更新 snapshot coverage,并把接受后的 snapshot 一起纳入评审。当前源码树没有遗留 .snap.new;新快照与已提交快照的差异需要结合测试语义判断。

Snapshot 测试还需要消除非语义噪声。路径、UUID、计时、终端宽度和颜色状态若不先规范化,会让同一 行为在不同机器上产生无意义 diff。TUI 测试中常见的 normalize_snapshot_paths、固定 terminal viewport 和 paused Tokio time 都服务于这一目的。

5. Schema 派生接口 ​

Codex 把需要被编辑器、SDK、Hook runner 和外部客户端消费的协议产物提交到仓库。它们不是普通 fixture:生成器会先清空目标目录,避免类型删除后留下幽灵文件,再写入完整结果。

text
codex-rs/
├── core/
│   └── config.schema.json                    # ConfigToml 的 JSON Schema
├── app-server-protocol/schema/
│   ├── typescript/
│   │   ├── *.ts                              # ts-rs 类型
│   │   ├── v2/*.ts                           # v2 API 类型
│   │   └── index.ts                          # 导出索引
│   ├── json/
│   │   ├── *.json                            # 单类型 schema
│   │   └── codex_app_server_protocol*.json   # bundle
│   └── precomputed/
│       ├── app-server-exports-stable.json.zst
│       └── app-server-exports-experimental.json.zst
└── hooks/schema/generated/
    └── <event>.command.<input|output>.schema.json

三组 schema 的共同闭环是“源类型 → 生成器 → 已提交产物 → drift test”。下面的时序图突出生成命令 只负责写产物,最终是否接受变化仍由测试和人工 diff 审阅决定。

如果 drift test 失败,首先审查 Rust 类型和 generator;直接修改 GeneratedFiles 会在下一次重生成时 被覆盖,也无法解释契约变化来源。

5.1 配置 schema ​

codex-config::schema::config_schema() 从 ConfigToml 生成 draft-07 schema,并补充仅靠 derive 无法表达 的组合约束;config_schema_json() 对 object key 排序,保证输出确定。仓库中的 fixture 由下面命令 更新:

bash
just write-config-schema

config_schema_matches_fixture 会重新生成内存 schema,先做 canonical JSON 比较,再写入临时文件做 精确文本比较。失败信息直接给出 unified diff 和更新命令。因此修改 ConfigToml 但漏掉 config.schema.json,不会等到发布时才发现。

源码位置:codex-rs/core/src/config/schema_tests.rs :: config_schema_matches_fixture

rust
#[test]
fn config_schema_matches_fixture() {
    let fixture_path = codex_utils_cargo_bin::find_resource!("config.schema.json")
        .expect("resolve config schema fixture path");
    let fixture = std::fs::read_to_string(fixture_path)
        .expect("read config schema fixture");
    let fixture_value: serde_json::Value =
        serde_json::from_str(&fixture).expect("parse config schema fixture");
    let schema_json = config_schema_json().expect("serialize config schema");
    let schema_value: serde_json::Value =
        serde_json::from_slice(&schema_json).expect("decode schema json");
    // 先比较 canonical value,排除对象 key 顺序等无语义差异。
    let fixture_value = canonicalize(&fixture_value);
    let schema_value = canonicalize(&schema_value);
    if fixture_value != schema_value {
        let expected = serde_json::to_string_pretty(&fixture_value)
            .expect("serialize fixture json");
        let actual = serde_json::to_string_pretty(&schema_value)
            .expect("serialize schema json");
        let diff = TextDiff::from_lines(&expected, &actual)
            .unified_diff()
            .header("fixture", "generated")
            .to_string();
        // 失败信息给出更新命令,但不会由测试自动覆盖受审阅的 fixture。
        panic!(
            "Current schema for `config.toml` doesn't match the fixture. \
Run `just write-config-schema` to overwrite with your changes.\n\n{diff}"
        );
    }

    // 再写临时文件做精确文本比较,防止格式化或末尾换行无意漂移。
    let tmp = TempDir::new().expect("create temp dir");
    let tmp_path = tmp.path().join("config.schema.json");
    write_config_schema(&tmp_path).expect("write config schema to temp path");
    let tmp_contents = std::fs::read_to_string(&tmp_path)
        .expect("read back config schema from temp path");
    #[cfg(windows)]
    let fixture = fixture.replace("\r\n", "\n");
    #[cfg(windows)]
    let tmp_contents = tmp_contents.replace("\r\n", "\n");

    assert_eq!(
        trim_single_trailing_newline(&fixture),
        trim_single_trailing_newline(&tmp_contents),
        "fixture should match exactly with generated schema"
    );
}

两阶段比较的失败含义不同:canonical diff 说明 schema 语义变了,精确文本 diff 说明仓库生成物没有按 确定格式提交。两者都通过才说明 fixture 可复现。

5.2 App Server契约 ​

App Server 的 source of truth 是 Rust protocol types、ts-rs 标注、schemars 导出逻辑以及 experimental registry。稳定生成命令是:

bash
just write-app-server-schema
just write-app-server-schema --experimental

稳定模式会整体重建 schema/typescript/ 与 schema/json/,再把 TypeScript、公开 JSON schema 和 internal JSON schema 压缩到 stable precomputed export。experimental 模式在临时目录生成包含实验 API 的树,只更新 experimental precomputed export,避免实验字段混入稳定 vendored schema。

对应测试不仅比较内容,还比较完整文件集合;删除一个 Rust 类型却遗留旧 .ts 文件同样会失败。 JSON 比较会规范化 object key,并只在能够为所有元素构造稳定 key 时排序 array;TypeScript 比较会 归一 CRLF 和生成 banner,使 Windows 与 Unix 只对协议语义产生 diff。

5.3 Hook schema ​

Hook input/output 类型由 schemars 生成 21 个 JSON 文件:

bash
just write-hooks-schema

write_schema_fixtures() 会清空 hooks/schema/generated/ 再重建。运行时的 schema_loader.rs 使用 include_str! 把这些文件编译进二进制,并在首次加载时解析;测试则在临时 目录重新生成全部文件,与已提交版本逐一比较。这里的 schema 同时是发布契约和运行时资源,不是只 供文档展示。

5.4 Protobuf 生成源 ​

少数内部协议同时保留 .proto 和生成的 .rs,例如 thread-config 与 exec-server relay。前者由 config/scripts/generate-proto.sh 调用 tonic_prost_build 写回 proto 目录;后者通过明确的 #[path = "proto/...rs"] 纳入模块,并被 Bazel target 列为源码。看到文件首行 @generated by prost-build 时,应回到 .proto 与对应生成入口修改,而不是手工维护字段编号。

6. Cargo 与 Bazel ​

Codex 不是“Cargo 项目附带一份 Bazel 文件”。日常 Rust 反馈以 Cargo/nextest 为主,CI 同时用 Bazel 验证 BUILD target、runfiles、跨平台依赖和发布构建。一个测试在 Cargo 通过,不代表它声明了 Bazel 需要的 binary、fixture 或 include_str! data。

6.1 just test语义 ​

仓库不推荐直接运行 cargo test,本地统一入口是:

源码位置:justfile :: test

makefile
# no-fail-fast 让一次验证尽量暴露全部失败,RUST_MIN_STACK 统一测试线程栈。
test *args:
    RUST_MIN_STACK=8388608 NEXTEST_PROFILE=local \
        cargo nextest run --no-fail-fast "$@"

源码位置:根 justfile :: test。--no-fail-fast 让一次运行尽量暴露所有失败;local profile 继承 default 配置。nextest 默认给失败测试重试一次,30秒判定一次 slow,连续两段后终止,并输出 JUnit。

并发并非越高越好。schema codegen、App Server subprocess、apply-patch CLI 和 Windows sandbox/process 测试分别进入受限 test group;本地 App Server 最多并发四个,Windows 重进程测试最多两个。这里的 串行化是资源隔离规则,不意味着被测代码只能串行工作。

源码位置:codex-rs/.config/nextest.toml :: profile.default, test-groups(节选)

toml
[profile.default]
# 慢测试超时和一次retry属于执行策略,不改变测试断言本身。
slow-timeout = { period = "30s", terminate-after = 2 }
retries = 1

[profile.default.junit]
path = "junit.xml"

[profile.local]
inherits = "default"

[test-groups.app_server_protocol_codegen]
max-threads = 1

[test-groups.app_server_integration]
max-threads = 1

# 本地最多四个App Server子进程,避免资源争用造成伪超时。
[test-groups.app_server_integration_local]
max-threads = 4

[test-groups.core_apply_patch_cli_integration]
max-threads = 1

[test-groups.windows_sandbox_legacy_sessions]
max-threads = 1

[test-groups.windows_process_heavy]
max-threads = 2

6.2 CI验证层次 ​

PR 的 blocking-ci.yml 汇总七类 required workflow:Bazel、blob size、cargo-deny、codespell、 repo checks、Rust CI 和 SDK。快速 Rust CI 根据改动路径选择 format、benchmark smoke、cargo-shear 和 argument-comment lint 等检查;SDK workflow 单独执行 Python 的 ruff/pytest 和 TypeScript 的 build/lint/Jest。

完整 nextest workflow 会先为目标平台建立 archive,再按 hash 分成四个 shard。Linux 与 Windows 还 单独构建 sandbox/helper binaries,并通过 CARGO_BIN_EXE_* 注入 archive 运行环境。平台矩阵覆盖 macOS arm64、Linux x64/arm64、Windows x64/arm64,并保存 Cargo timings 与 JUnit 报告。

这说明 nextest archive、helper staging 目录、timings 和 JUnit 都是 CI transport artifact;它们用来 把“编译”与“分片执行”解耦,不属于需要提交的生成物。

每个主要 job 末尾还调用 check-clean-worktree。任何测试或生成器若在 checkout 中留下 tracked diff 或普通 untracked file,job 都会失败。这能捕获“测试偷偷改了仓库”的问题,但生成物是否与源类型 一致仍主要由专用 fixture-match tests 保证。

7. 按改动选择 ​

改动类型最小行为测试必须同步的资产额外验证面
纯函数、解析器、序列化sibling unit test通常无相关 crate just test -p
Agent Turn、工具或审批逻辑Core integration test模型/SSE fixture 仅按需检查 request 与 event 两端
App Server RPC公共 JSON-RPC integration testREADME 与稳定/实验 schemaprotocol crate test
TUI 可见输出TUI 行为测试审阅并接受 .snap.new不同 viewport/状态路径
apply-patch 规范portable scenario testinput/patch/expectedCLI 与平台路径语义
ConfigToml 或嵌套配置config schema testcore/config.schema.jsonjust write-config-schema
Hook wire typeHook schema testhooks/schema/generated/runtime embedded schema load
App Server 类型或 TS 标注schema fixture testsTS、JSON、stable/experimental zststable/experimental filter
.proto协议/relay tests对应 generated .rsCargo 与 Bazel compile
测试中启动 workspace binaryintegration testBUILD data/deps 按需cargo_bin() 的 Cargo/Bazel 双路径
SDK public APIpytest 或 JestSDK contract fixture 按需真实 App Server smoke

最小测试不是最少运行一个命令,而是选择能观察改动边界的测试。修改内部 parser 时无需启动完整 App Server;修改 Turn 工具回灌时,只测 parser 又覆盖不到真正风险。对于跨层改动,先跑受影响 crate 缩短反馈,再让完整 CI 覆盖 Bazel、SDK 和平台矩阵。

8. 失败产物定位 ​

失败表现它通常说明什么不应立即做什么
普通 assert_eq diff行为或结构对象变化拆成大量字段断言掩盖差异
.snap.new 出现可见输出与已接受契约不同未审阅就全量 accept
fixture 最终目录不等规范场景、输入或实现至少一项改变从实际输出自动覆盖 expected
schema 文件集合不等类型新增/删除与 vendored tree 漂移只删当前报错的单个文件
stable schema 含实验字段experimental filter/标注错误把实验字段手改出 JSON
Cargo 通过、Bazel 找不到资源BUILD data 或 runfiles 解析缺失硬编码 target/ 路径
nextest 本地偶发通过、CI 超时共享资源、进程数或平台条件问题无限增加 retry 掩盖竞态
clean-worktree 失败测试/生成步骤留下文件或 drift忽略 untracked 文件继续发布
SDK contract test 失败Rust wire schema 与客户端公开 API 不一致只修客户端类型而不核对 source of truth

阅读测试失败时,应沿“source → harness → input asset → observed output → expected result”反向 定位。测试代码决定观察点,fixture 决定输入,snapshot/schema 决定预期;只有先确认这三个角色,才 能判断应该修实现、修测试,还是运行生成器同步派生产物。

9. 仓库资产统计 ​

以下命令从当前源码目录和仓库文件列表读取统计结果。它们不把 target/ 或其他本地产物当成源码资产。

bash
# 含#[cfg(test)]或mod tests标记的Rust文件;这是“文件数”,不是测试函数数。
rg -l '#\[cfg\(test\)\]|mod tests' codex-rs --glob '*.rs' | wc -l

# tests/suite与fixture中的受跟踪文件。
git ls-files 'codex-rs/**/tests/suite/*.rs' | wc -l
git ls-files 'codex-rs/**/fixtures/**' | wc -l

# 全仓库snapshot、TUI snapshot以及未接受的新snapshot。
git ls-files | rg '\.snap$' | wc -l
git ls-files 'codex-rs/tui/**' | rg '\.snap$' | wc -l
git ls-files | rg '\.snap\.new$' | wc -l

# Hook和App Server的受跟踪schema文件。
git ls-files 'codex-rs/hooks/schema/generated/*.json' | wc -l
git ls-files 'codex-rs/app-server-protocol/schema/typescript/**' | wc -l
git ls-files 'codex-rs/app-server-protocol/schema/json/**' | wc -l
统计项结果口径限制
有测试模块标记的 Rust 文件1138一个文件可含多个或零个实际 #[test]
tests/suite/*.rs300不含近场 unit test 与其他命名集成入口
fixture 文件97只统计路径包含 fixtures/ 的受跟踪文件
全仓库 / TUI *.snap759 / 705snapshot 数不等于测试数
*.snap.new0只说明当前目录没有新的 snapshot 文件
Hook generated JSON21由事件输入/输出组合决定,不等于Hook事件数
App Server TS / JSON schema688 / 295文件数不等于RPC method数

这些命令适合比较版本或快速了解资产规模,不适合衡量 statement、branch 或行为覆盖率。若要统计 Cargo 明确 test target,应 改用 Cargo 工作空间全景 的 metadata 查询;当前源码中约有 32 个 package 包含显式 test target,但仍不含 library 内联测试。

10. 资产地图与专题 ​

改动落点先进入的正文最小验证入口
Thread/Turn、Task、关闭运行时任务拓扑、Session关闭流程core/tests/all.rs 与 TestCodexBuilder
App Server RPC、握手、背压Codex 产品形态全景、CodexThread背压app-server/tests/all.rs 与 TestAppServerBuilder
对象和历史投影核心数据对象关系protocol projection tests 与 rollout fixture
文件、网络、平台sandboxCodex信任边界、跨平台能力矩阵policy unit test+目标平台fixture
feature与设置约束Core运行时能力开关、Session设置约束config tests+schema fixture
不确定选哪个harnessCodex源码阅读路线文末 TestCodex / TestAppServer 完成检查

完成测试地图阅读的标志,是已经找到能够因目标行为变化而失败的测试或生成物比较。只指出文件数量、snapshot 目录或 CI workflow 名称,还不足以解释行为。