ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

VS Code Agent Sessions 会话导航与历史加载 E2E 场景剖析:从自然语言场景到确定性回归验证

VS Code Agent Sessions 会话导航与历史加载 E2E 场景剖析:从自然语言场景到确定性回归验证 VS Code Agent Sessions 会话导航与历史加载 E2E 场景剖析从自然语言场景到确定性回归验证【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode本文围绕 VS Code 仓库中 Agent Sessions代理会话工作台的端到端测试场景04-navigate-sessions讲解会话之间来回切换并验证历史消息正确加载这一核心交互的测试目标、底层 UI 行为以及它如何被 compile-and-replay编译—回放测试架构翻译成可确定性执行的playwright-cli命令。读者将掌握该场景的逐步语义、.commands.json生成物结构、测试运行方式以及如何书写与维护同类会话场景。场景文档说了什么仓库中 src/vs/sessions/test/e2e/scenarios/04-navigate-sessions.scenario.md 是一个人类可读的 E2E 场景scenario全文以 H2## Steps下的自然语言编号列表组织共 9 步在聊天输入框输入explain the code按 Enter 提交校验聊天区出现响应点击New Session按钮在聊天输入框输入build the project按 Enter 提交校验聊天区出现响应在会话列表中点击另一个会话校验当前会话已切换且聊天内容与之前不同它的测试意图集中且清晰一个 Agent 工作台需要支持创建多个会话Session、在会话间导航并且每次切换都必须把对应会话的历史聊天记录正确恢复出来。这是一个典型的 状态隔离 历史加载 回归验证场景——如果会话模型把多条会话的上下文串了或切换时没有正确按会话加载历史第 8、9 步就会失败。该场景不是孤立的它隶属于src/vs/sessions/test/e2e/下的场景族编号01–05场景文件按文件名排序后顺序执行。兄弟场景分别覆盖01-chat-response发送消息并收到响应、02-chat-with-changes聊天产出真实文件 diff、03-session-in-sidebar发送消息后侧边栏出现会话、05-full-workflow把会话与终端标签、Changes 视图串成完整工作流。前置理解被测试的会话是什么该场景针对的是 src/vs/sessions 目录实现的Agent Sessions 工作台——一个以会话为中心组织聊天、变更与文件操作的环境内部文档见 src/vs/sessions/README.md、src/vs/sessions/SESSIONS.md。从目录结构可以推断其 UI 构成browser/parts/sessionsPart.ts 与 browser/parts/sessionView.ts 负责承载会话列表 / 会话视图——即场景第 8 步点击的目标contrib/sessions/browser 下有 27 个.ts文件实现会话列表、会话条目的管理与渲染contrib/chat/browser/newSession.ts 定义了NewSessionChangeTyperepoUri、isolationMode、branch、options、disabled、agent对应新建会话时要变更的属性维度contrib/chat/browser/sessionsChatHistory.ts 则暗示了会话 → 聊天历史的加载机制。因此场景中的 New Session 按钮、会话列表sessions list、会话条目都有对应的真实 UI 部件切换会话时被验证的内容不同本质上是工作台按照当前激活会话重新渲染其专属的历史消息序列05-full-workflow场景还进一步验证终端标签会随会话切换在session-1/session-2之间来回改变佐证会话切换会带动一组相关联的会话级 UI 状态。逐步拆解每一步在测什么结合场景族与 Mock 架构详见 test/e2e/README.md9 个步骤可归纳为三个测试片段步骤用户动作真实 UI 行为验证点 / Mock 行为1–3explain the code→ Enter消息经 Chat Widget → ChatService 提交给 Chat agent出现聊天响应。生成物中该断言具体化为ASSERT_VISIBLE: This project has a simple structure with a main entry point and utility functions.4点击New Session创建并激活一个全新的、空的会话保留旧会话在列表中步骤 5–7 中旧会话历史不再显示新输入进入新会话上下文5–7build the project→ Enter同上提交路径该消息关键字命中带textEdit的 canned 响应出现新响应。生成物中断言ASSERT_VISIBLE: Ill help you build the project. Here are the changes:8点击会话列表中的另一会话工作台把激活态切回第一个会话生成物中以click listitem explain the code定位会话条目——可见会话条目以首条用户消息文本作为可访问性标签9—视图重新加载目标会话的历史生成物中两条断言ASSERT_VISIBLE: explain the code条目仍可见与ASSERT_VISIBLE: This project has a simple structure...第一条会话的历史响应被正确恢复可以看到第 9 步的真正杀手锏是断言恢复出来的内容是第一段会话特有的 canned 响应文本而不是第二段会话的build the project响应。这样只要历史加载错位例如两个会话共享同一份上下文断言立刻失败。需要说明的是这些 canned response 来自测试 Mock agent 的关键字匹配响应具体定义在 test/web.test.ts 的getMockResponseWithEdits(message)该函数针对build the project这类消息返回Ill help you build the project. Here are the changes:文本并附带编辑进度项。真实 LLM 与真实 git 均被 Mock测试验证的是除外部后端之外的整条真实代码路径。场景如何变成可回放的命令compile-and-replay 架构.scenario.md只是剧本真正被测试运行器执行的是配套的.commands.json。这套 E2E 采用compile-and-replay架构由playwright/cli与 Copilot CLI 驱动README 对此有完整说明包含两个阶段Phase 1 — 生成npm run generate需要 LLM运行一次生成脚本generate.cjs对每个.scenario.md启动 Sessions Web 服务并打开页面 → 抓取当前页面的可访问性树accessibility tree快照 → 把每个自然语言步骤连同快照交给 Copilot CLI由其给出精确的playwright-cli命令如click e143、type hello→ 执行命令推进 UI → 将编译结果写入scenarios/generated/下的同名.commands.json。这些.commands.json会被提交到 git作为人人可复现的确定性测试计划。Phase 2 — 回放npm test无需 LLM快且确定测试运行器 test.cjs 读取每个.commands.json机械地逐条回放playwright-cli命令并执行断言全程没有 LLM 调用、没有正则猜 UI。本场景的编译产物场景04-navigate-sessions的生成产物为 src/vs/sessions/test/e2e/scenarios/generated/04-navigate-sessions.commands.json。其头部记录场景名与生成时间steps数组把 9 个人类步骤映射为原子命令{ scenario: Scenario: Navigate between sessions and verify history loads, generatedAt: 2026-03-06T04:56:01.957Z, steps: [ { description: Type \explain the code\, commands: [click textbox \Chat input\, type \explain the code\] }, { description: Press Enter to submit, commands: [click textbox \Chat input\, press Enter] }, { description: Verify there is a chat response, commands: [# ASSERT_VISIBLE: This project has a simple structure with a main entry point and utility functions.] }, { description: Click button \New Session\, commands: [click button \New Session\] }, { description: Click on a different session in the sessions list, commands: [click listitem \explain the code\] }, { description: Verify the session changed and the content in the chat is different, commands: [# ASSERT_VISIBLE: explain the code, # ASSERT_VISIBLE: This project has a simple structure with a main entry point and utility functions.] } ] }这个文件很好地展示了两个阶段的交接方式场景描述description保留人类可读步骤用于失败时输出清晰的错误上下文动作型步骤编译成语义化命令如click button New Session、click textbox Chat input、press Enter回放时运行器先从实时快照解析出对应控件引用再执行见test.cjs的resolveSemanticCommand校验型步骤编译成snapshot 注释式断言即# ASSERT_VISIBLE: text运行器执行快照后检查文本是否可见。test.cjs支持的注释断言格式README 与源码均可确认包括ASSERT_VISIBLE检查快照含该文本、ASSERT_DISABLED检查按钮带[disabled]、ASSERT_ENABLED检查按钮不带[disabled]。场景文件如何被解析场景解析逻辑在 common.cjs 的parseScenario()中以#开头行作为场景名/^## steps?$/i之后的-或1.有序列表项全部视为步骤遇到其他##标题即结束解析discoverScenarios()会扫描scenarios/目录下所有*.scenario.md并按文件名排序。这解释了场景文件的硬性格式约定首行为# Scenario: ...随后是## Steps及其下的编号列表任何其他 Markdown 章节都不会被当作执行步骤。复现与运行按 test/e2e/README.md 的说明本场景的运行前提与命令如下前置条件仓库根目录已编译npm install npm run compile产物out/在src/vs/sessions/test/e2e下执行npm install安装依赖只有运行npm run generate才需要本地有 Copilot CLIcopilot --version校验。启动服务的等价脚本为npm run serve即运行仓库根目录的 scripts/code-sessions-web.js 并以--mock模式启动该标志会启用 Mock 后端。回放执行cd src/vs/sessions/test/e2e npm test需要重新编译场景UI 变化导致控件引用过期、新增或修改场景步骤时执行npm run generate也可按前缀选择性重编npm run generate -- 04-navigate。Mock 服务的最小集合可参会话列表来自 READMEIChatEntitlementService返回ChatEntitlement.Free、IDefaultAccountService返回假登录账号、IGitService立即解析、chat agent 提供 canned 响应、mock-fs://由InMemoryFileSystemProvider在工作台内直接注册、GitHub 认证为始终登录的 Mock 扩展、PR 命令为空操作。其余服务ChatEditingService、ChatModel、ChangesViewPane、diff 编辑器、context keys 等全部走真实实现——Mock 是数据唯一的注入点。与相邻场景的协同关系04场景不是凭空出现的它与场景族互为补充共同逼近多会话完整工作流03-session-in-sidebar.scenario.md 先验证发送一条消息后侧边栏出现对应会话——这是04第 8 步能够点击列表条目的前置能力02-chat-with-changes.scenario.md 验证会话内聊天会驱动 Changes 视图产生真实 diff05-full-workflow.scenario.md 把会话与终端标签联动新建session-2后终端标签从session-1变为session-2点击回第一个会话后又变回session-1——从另一个维度再次印证会话切换 一组会话级状态的整体恢复。因此04专注的是会话模型两条不变量(1)多个会话可共存New Session 不销毁旧会话(2)每个会话持有独立历史切换时按目标会话恢复点击列表条目后内容正确切换。编写与扩展此类场景的要点若要在仓库中新增会话导航类场景README 与既有场景文件给出了可复制的实践在src/vs/sessions/test/e2e/scenarios/下新建NN-描述.scenario.md文件名数字前缀决定执行顺序首行写# Scenario: 一句话描述随后是## Steps与编号列表步骤用朴素英文描述示例模式如Click button New Session、Type build the project in the chat input、Verify the session changed and the content in the chat is different——agent 能理解自然语言不必局限于固定句式尽量用 UI 上的精确标签如按钮名、会话条目文本定位目标每条目只做一个动作保持步骤原子化便于失败定位运行npm run generate生成.commands.json再npm test验证最后把.scenario.md与.commands.json一并提交若改动涉及 Mock 的文件编辑关键字需同步更新 test/web.test.ts 的getMockResponseWithEdits()与 mock 扩展的文件仓库extensions/sessions-e2e-mock并保证路径位于/mock-repo/之下。一个实用建议README 亦强调这类场景的断言应落在文本内容与可见性上例如校验切换回来后能看到第一段会话特有的响应文本而不是断言 Mock 内部实现细节这样当 Mock 文件内容演进时场景依然稳定、可长期回归。小结04-navigate-sessions用 9 行自然语言精炼地锁定了一条高价值的会话产品级回归路径创建第二个会话、回到第一个会话、并断言各自历史完整隔离加载。透过 .commands.json 可以看到它在真实 Agent Sessions 工作台上的确定性执行形态而它对会话条目以首条消息为标签的依赖、对 canned 响应文本的断言策略也为我们理解该工作台会话 独立历史容器的核心模型提供了最直观的测试侧证据。【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进