xiaohack's Blog - 自动化测试
type: channel
link: https://blog.xiaohack.org/tag/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/
items: 什么是 Headless Browser？B2Proxy解析无头浏览器的原理、应用场景与真实价值
items: 【教程】用 AionUI & Chrome MCP Tools控制自己的 Chrome浏览器（带浏览器原始数据，非新开），完全免费
items: 快速上手：LangChain + AgentRun 浏览器沙箱极简集成指南
items: 测试用例越堆越多？用 Apifox 测试套件让自动化回归更易维护
items: 请教一个 openspec 问题
items: Galaxy比数平台功能介绍及实现原理｜得物技术
items: AI Coding与单元测试的协同进化：从验证到驱动
items: Meta 运用基于大型语言模型的变异测试提升合规覆盖率
items: 同时开 5 个智能体，把编程玩成了战略游戏

什么是 Headless Browser？B2Proxy解析无头浏览器的原理、应用场景与真实价值
type: item
date: 2026-02-10T14:46:52+08:00
description: 随着自动化技术、数据采集和智能测试的普及，“Headless Browser（无头浏览器）”已经从一个偏工程师内部使用的工具，逐渐演变为数据工程、爬虫系统、自动化测试乃至 AI 应用中的核心组件。很多人听说过这个概念，却并不真正理解它的工作原理、真实能力以及在复杂网络环境中的价值。本文将系统性地解析什么是 Headless Browser，它与传统浏览器的本质区别，以及它在现代互联网应用中的实际意义。Headless Browser 的基本定义Headless Browser，直译为“无头浏览器”，这里的“头”指的是图形用户界面。也就是说，它本质上是一个没有可视化界面的浏览器内核，能够像普通浏览器一样解析 HTML、执行 JavaScript、加载 CSS、发起网络请求、处理 Cookie 和本地存储，但所有过程都在后台完成，不向用户展示页面。从功能角度看，Headless Browser 并不是“阉割版浏览器”，恰恰相反，它在网页渲染和脚本执行层面，与完整浏览器几乎一致，只是去掉了 UI 渲染这一步。正因为这一特性，它非常适合被程序控制，用于自动化任务。无头浏览器是如何工作的理解 Headless Browser 的关键，在于理解现代网页的加载逻辑。当你用普通浏览器访问一个网站时，背后会经历一整套流程：浏览器发起请求、接收 HTML、解析 DOM、加载 CSS、执行 JavaScript、请求接口数据、动态更新页面内容。Headless Browser 运行的正是这套完整流程，只是整个过程由代码驱动，而不是由用户点击和操作触发。开发者可以通过脚本控制它打开页面、等待资源加载、模拟滚动、填写表单、点击按钮，甚至执行复杂的交互逻辑。从服务器的角度看，它看到的并不是一个“工具”，而是一个行为极其接近真实用户的浏览器环境。Headless Browser 与普通爬虫的根本区别很多初学者会把 Headless Browser 与传统 HTTP 爬虫混为一谈，但两者在能力层级上有明显差异。传统爬虫更多依赖直接请求接口或页面源代码，适合结构简单、反爬较弱的网站。但面对大量使用前端框架、动态渲染、接口签名和行为校验的网站时，传统爬虫往往寸步难行。Headless Browser 的优势在于，它可以完整执行前端逻辑，获取最终渲染后的真实页面状态。这意味着即使网站内容完全由 JavaScript 动态生成，也依然可以被正确获取。在很多复杂网站场景中，无头浏览器已经成为“唯一可行方案”。为什么 Headless Browser 会被重点风控正因为 Headless Browser 具备强大的模拟能力，它也成为各大平台重点识别和限制的对象。近年来，网站风控系统不再只看 IP 和请求频率，而是更加关注浏览器指纹、行为轨迹和执行环境。一些常见的 Headless Browser 在默认配置下，会暴露出明显的自动化特征，例如特定的 JavaScript 属性、异常的渲染行为或不符合真实用户的操作节奏。这也是很多人会遇到“明明用了无头浏览器，却还是被封”的根本原因。Headless Browser 本身不是问题，问题在于环境是否足够真实、行为是否足够自然、网络身份是否可信。无头浏览器与网络环境的关系很多人忽略了一个关键问题：Headless Browser 再强，也只是“浏览器”，它依然运行在某个网络环境之中。如果网络出口本身存在异常，例如 IP 来源不可信、ASN 被标记、地址被滥用过，那么即使浏览器层面完全模拟真实用户，依然可能在请求阶段就被拦截。这也是为什么在高风控场景下，无头浏览器往往需要配合更稳定、更接近真实用户的网络环境使用。真实住宅网络、干净的出口地址，往往比复杂的浏览器参数伪装更重要。Headless Browser 是否等同于“自动化作弊”这是一个经常被误解的问题。Headless Browser 本身是一种技术工具，它既可以用于合规的自动化测试、数据分析和效率提升，也可能被滥用于违规操作。关键并不在于工具本身，而在于使用方式是否符合平台规则和法律边界。在合规使用前提下，无头浏览器反而是很多正规企业和开发团队不可或缺的基础设施。未来趋势：Headless Browser 正在变得“更像人”随着反自动化技术的不断升级，Headless Browser 也在持续进化。从早期简单执行脚本，到如今强调完整指纹一致性、行为轨迹自然化和环境真实性，无头浏览器正在向“高度拟真浏览环境”发展。未来，它不再只是一个技术工具，而是整个网络身份系统中的一个重要组成部分。结语Headless Browser 并不是一个神秘或危险的概念，它只是现代 Web 技术发展下的必然产物。理解它的原理、边界和真实价值，远比盲目使用或一味回避更重要。当你真正把它看作一个“没有…

【教程】用 AionUI & Chrome MCP Tools控制自己的 Chrome浏览器（带浏览器原始数据，非新开），完全免费
type: item
date: 2026-01-25T08:05:42+08:00
description: 第一步：开启 Chrome 远程调试权限这是所有操作的前提，必须手动开启。打开 Chrome 浏览器，在地址栏输入：chrome://inspect/#remote-debugging勾选 “Allow remote debugging for this browser instance”。确认下方出现：Server running at: 127.0.0.1:9222（这表示“门”已打开）。第二步：配置 MCP 服务AionUI 图形界面配置进入 AionUI 的 Settings（设置） → Tools Settings（工具设置）。在 MCP Management 区域点击 Add MCP Service。选择 Add via JSON，粘贴以下配置：{ "mcpServers": { "chrome-devtools": { "command": "npx", "args": [ "-y", "chrome-devtools-mcp@latest", "--autoConnect", "--channel=stable" ] } } } 第三步：激活连接（关键动作）配置完成后，Gemini 并不会立刻接管浏览器，需要一次“握手”：在 Gemini CLI 或 AionUI 中输入第一个指令，例如：截取当前网页的屏幕。切换回 Chrome 浏览器：你会看到页面顶部弹出一个系统确认框，询问 “Allow incoming debugging connection?”。点击 Allow（允许）。浏览器顶部出现横幅（显示“正在受自动测试软件控制”），说明连接成功。第四步：实战常用指令连接成功后，你可以直接用自然语言指挥 Gemini 处理你当前看到的网页：视觉分析： “帮我截个图，分析一下现在的 UI 布局有没有错位？”性能诊断： “分析当前页面的性能，告诉我 LCP（最大内容绘制）是多少，怎么优化？”代码调试： “检查当前页面的 Console 控制台，有没有报错？如果有，帮我解释原因。”网页抓取与操作： “提取当前网页中所有商品的价格并列成表格。”“帮我点击页面上的‘提交’按钮。”（AI 会通过 DOM 树自动定位元素）推荐模型：Gemini 3 Flash、Gemini 3 Pro、GLM 4.7（英伟达无限免费 API）使用案例：感谢 的AionUIAionUi V1.7.4 更新：兼容了Newapi（Cowork开源版可以用公益站/中转站了）也欢迎使用我的 AMC，这个教程的方法也都是我用 AMC 的深度搜索功能学会的AMC更新：支持Markdown 转 PDF、划词 TTS推荐使用 @bbbugg 佬的AIStudioToAPI 构建自己的API 池https://linux.do/t/topic/1371269【二改】二改build反代(AIStudio to API)，优化云端部署📌 转载信息来源： https://linux.do/t/topic/1510601原作者： yeahhe转载时间： 2026/1/25 08:06:46

快速上手：LangChain + AgentRun 浏览器沙箱极简集成指南
type: item
date: 2026-01-22T17:35:21+08:00
description: 作者：辰泉前言在 Agentic AI 时代，智能体需要与真实世界交互，而浏览器是连接虚拟世界与现实世界的重要桥梁。AgentRun Browser Sandbox 为智能体提供了安全、高性能、免运维的浏览器执行环境，让 AI Agent 真正具备“上网”的能力——从网页抓取、信息提取到表单填写、自动化操作，一切皆可实现。AgentRun Browser Sandbox 介绍什么是 Browser Sandbox?Browser Sandbox 是 AgentRun 平台提供的云原生无头浏览器沙箱服务，基于阿里云函数计算（FC）构建。它为智能体提供了一个安全隔离的浏览器执行环境，支持通过标准的 Chrome DevTools Protocol (CDP) 远程控制浏览器实例。核心特性无头浏览器能力内置 Chromium/Chrome 浏览器，支持完整的 Web 标准原生兼容 Puppeteer、Playwright 等主流自动化框架支持通过 CDP 协议进行精细化控制实时可视化内置 VNC 服务，支持实时查看浏览器界面提供操作录制功能，方便调试和回放支持通过 noVNC 客户端在网页中直接交互安全与隔离每个沙箱实例运行在独立的容器环境中文件系统和进程空间完全隔离支持 WSS 加密传输，确保数据安全Serverless 架构按需创建，按量付费，无需提前预置资源快速弹性伸缩，支持高并发场景零运维，无需管理服务器和浏览器依赖主要应用场景AI Agent 赋能： 为大模型提供“眼睛”和“手”，执行网页浏览、信息提取、在线操作等任务自动化测试： 在云端运行端到端（E2E）测试和视觉回归测试数据采集： 稳定、高效地进行网页抓取，应对动态加载和反爬虫挑战内容生成： 自动化生成网页截图或 PDF 文档上手使用 AgentRun Browser SandboxAgentRun SDK 快速介绍后续的内容将基于 AgentRun SDK 进行，因此我们先对 SDK 进行简要介绍。Agentrun SDK 是一个开源的开发者工具包，本期介绍 Python 版本。其旨在简化智能体与 AgentRun 平台各种服务（包括 Browser Sandbox）的集成。它提供了统一的接口，让您可以用几行代码就将沙箱能力集成到现有的 Agent 框架中。SDK 的核心功能如下：统一集成接口提供对 LangChain、AgentScope 等主流框架的开箱即用支持统一的模型代理接口，简化多模型管理标准化的工具注册机制Sandbox 生命周期管理自动创建和销毁沙箱实例支持会话级别的状态保持灵活的资源配置和超时控制安装 AgentRun SDKpip install agentrun-sdk[playwright,server]注意： 确保您的 Python 环境版本在 3.10 及以上。基本使用示例以下是使用 AgentRun SDK 创建和管理 Browser Sandbox 的核心代码：from agentrun.sandbox import Sandbox, TemplateType from playwright.sync_api import sync_playwright # 创建 Browser Sandbox sandbox = Sandbox.create( template_type=TemplateType.BROWSER, template_name="your-template-name", sandbox_idle_timeout_seconds=300 ) # 获取 CDP URL（用于 Playwright 连接） cdp_url = sandbox.get_cdp_url() # 使用 Playwright 连接并操作 with sync_playwright() as p: browser = p.chromium.connect_over_cdp(cdp_url) page = browser.contexts[0].pages[0] page.goto("https://www.example.com") page.screenshot(path="screenshot.png") browser.close() # 销毁 Sandbox sandbox.delete()关键概念：template_name： 控制台创建的浏览器环境模板cdp_url： 用于 Playwright/Puppeteer 连接vnc_url： 用于实时查看浏览器画面（可通过 sandbox.get_cdp_url() 获取）注意： 由于所有浏览器操作都在云端进行，您无需在本地安装浏览器。Playwright 仅用于通过 CDP 协议连接到云端的浏览…

测试用例越堆越多？用 Apifox 测试套件让自动化回归更易维护
type: item
date: 2026-01-21T16:20:14+08:00
description: 当项目中的接口测试用例和测试场景越积越多，单独管理和执行它们的成本会急剧上升。原本用于保障质量的自动化测试，自身反而成了维护的负担。传统的维护方式是手动点选。当项目沉淀了大量用例和测试场景时，手动核对哪些该入库、哪些该回归，会成为沉重的体力成本。Apifox「测试套件」通过动态模式解决了这个问题。它不再死板地记录 ID，而是保存一套筛选规则，例如按目录、标签、优先级等条件进行组合筛选。在每次运行前，套件会根据筛选规则，自动组合所有符合规则的用例和测试场景。这意味着你只需专注于测试内容的编写和打标，新增的测试资产就会自动进入 CI/CD 流水线，真正实现无人值守的持续集成。最终，所有执行项的结果会被汇总到一份聚合报告中，便于集中分析和定位问题。创建并编排你的第一个套件将 Apifox 更新到最新版本后，在「自动化测试」模块中，可以找到「测试套件」的分类。点击其右侧的 ... 按钮，选择「新建测试套件」。在弹出的窗口中输入一个描述性的名称，配置相关的优先级或者标签，一个空的测试套件就创建完成了。创建完成后，核心工作是向这个套件中添加内容。测试套件的内容可以是单个的「接口测试用例」，也可以是包含多个步骤的「测试场景」。添加测试内容：静态与动态点击「添加接口测试用例」或「添加测试场景」时，会看到「静态」和「动态」两种模式的选项。这两种模式决定了测试套件如何管理其包含的测试项，适用于不同的维护策略和测试目标。静态模式，顾名思义，是精确地、不变地指定要执行的测试项。当你以静态模式勾选某些用例时，系统记录的是这些用例的唯一 ID。即使后续这些用例的源目录增加了新的用例，或者用例本身被移动，这个套件的执行范围也不会改变。它的确定性很高，确保了每次运行的内容完全一致。动态模式则完全不同。它不记录具体的用例 ID，而是保存一套 “筛选规则”，例如 “某个目录下的所有用例” 或 “所有标签为「语义合法」的用例”。又或者是 “所有标记为 P0 优先级的测试场景”。在动态模式下，每次运行测试套件时，系统都会根据这套规则重新扫描整个项目，将所有当前符合条件的用例动态地纳入执行计划。这意味着，只要测试用例的属性（如所在目录、标签、优先级）符合规则，它就会被自动包含进来。静态模式与动态模式：如何选择？这两种模式没有绝对的优劣之分，而是服务于不同的管理需求。选择哪种模式，取决于你希望测试套件具备怎样的维护特性。对于需要严格控制范围的专项测试，静态模式更可靠。而对于需要持续迭代、自动纳新的回归或冒烟测试，动态模式则能极大地降低维护成本。为了更清晰地理解两种模式的差异，可以通过下表进行对比：执行顺序与高级配置添加完测试内容后，可以在编排列表中通过拖拽调整它们的执行顺序。在执行项（测试场景）的右侧，可以对套件的运行行为进行更细粒度的控制。例如，「遇到错误时」 选项可以决定当某个步骤失败后是继续执行、跳过当前轮次还是立即终止整个运行。「循环次数」则可以将整个套件重复执行多次，用于简单的稳定性测试。这些配置让测试套件不仅仅是一个用例的集合，更是一个可控的执行流程。运行测试套件构建好测试套件后，下一步就是执行它。Apifox 提供了从本地手动运行到云端自动化执行的多种方式，以适应不同阶段和环境的需求。本地可视化运行最直接的运行方式是在 Apifox 客户端界面中，点击「运行」按钮。这种方式会从本地机器发起请求，适用于在开发和调试阶段进行小规模、快速的测试验证。在运行配置界面，可以临时切换「运行环境」，或设置在运行结束后发送通知。运行完成后，Apifox 会生成一份本次执行的测试报告，并在界面中以可视化方式展示。报告中会按执行顺序列出每一个接口测试用例和测试场景的结果，清晰标识成功和失败状态，点击具体测试项可查看更详细的报告。通过 CLI 运行当测试规模较大，或者需要在无图形界面的服务器上执行时，Apifox CLI 是更高效的选择。它是一个命令行工具，可以将 Apifox 中的测试能力延展到任何终端环境。要使用 CLI 运行，首先需要安装 Apifox CLI，并确保其版本为最新。完成安装或升级后，可以在测试套件的「CI/CD」标签页中找到自动生成的命令行：将这条命令复制到终端中执行，即可在命令行看到与图形界面一致的测试过程和结果。运行结束后，它还会在当前目录下生成一个 apifox-reports/ 文件夹，里面包含了 HTML 格式的详细测试报告。通过 CLI 运行的方式是实现 CI/CD 的基础。可以将这条命令集成到 Jenkins、GitLab CI 或 GitHub Actions 的脚本中，在代码合并等关键节点自动触发回归测试。通过定时任务运行Apifox 内置了「定时任务」功能。在测试套件的「定时任务」标签页，可以新建一个任务，设置其运行周期和运行环境。与本…

请教一个 openspec 问题
type: item
date: 2026-01-21T02:28:05+08:00
description: 不太懂 openspec ，最近了解了一下。自己在某个仓库使用 openspec 写了一次需求，也观察了一下 openspec 自身是怎么使用的，发现 openspec 的 spec 似乎就是在用自然语言描述代码逻辑行为的各种 case 。以 openspec 仓库自身的 spec 为例，发现 spec.md 文件本身是在描述代码的行为逻辑。比如 openspec 的某个 spec.md 对应行为就是这个文件： https://github.com/Fission-AI/OpenSpec/blob/8332a098118a6584a7104ccfe8e46669a1c24b7d/src/utils/change-utils.ts#L112 ，spec.md 本身贴在末尾我的问题是: 这样的 spec 存下来有什么意义？因为我理解存下来是为了后续有其他需求迭代时给 ai 看的，那为什么不直接让 ai 去读代码来理解现有的逻辑呢？我理解大型项目让 ai 工作是需要知识库的，但是 openspec 的 spec 更像一个细节说明书，而不是类似纲领的知识库。是不是说在 openspec 的工作流里面 spec 才是代码仓库的行为核心准则，理论上基于 spec.md 可以随时生成一套具体实现可能不一致，但行为一致的代码。 openspec 的工作流程是先让 AI 进行 plan ，然后迭代 plan ，直到 AI 给出 plan 满意了，然后 AI 开始进行 coding 。这个 plan 的流程现在 antigravity 等也能做到。感觉 plan 并不是 openspec 的重点，spec.md 才是重点是吗？如果说期望的流程是先和 ai 讨论出充满细节的 spec ，再让 ai 开始 coding ，有种变成了自然语言描述写代码的感觉，这个感觉非常怪。 基于 1 的末尾提出的“spec 才是代码仓库的行为核心准则”的想法，假设需要落地到一个前端项目，那按照这个 spec 粒度，我感觉每个 tsx 文件都需要一个 spec 去描述它的规范行为。这个感觉就更怪了 有没有实践比较多的朋友能给一些输入，分享一些经验，或者思考？附上的 spec.mdchange-creation 规范目的（ Purpose ）提供用于以编程方式创建和校验 OpenSpec change 目录的工具函数。需求（ Requirements ）需求：Change 创建（ Change Creation ）系统 必须（ SHALL ） 提供一个函数，用于以编程方式创建新的 change 目录。场景：创建 change 当（ WHEN ） 调用 createChange(projectRoot, 'add-auth') 那么（ THEN ） 系统会创建 openspec/changes/add-auth/ 目录 场景：拒绝重复的 change 当（ WHEN ） 调用 createChange(projectRoot, 'add-auth')，且 openspec/changes/add-auth/ 已存在 那么（ THEN ） 系统抛出一个错误，表明该 change 已存在 场景：必要时创建父目录 当（ WHEN ） 调用 createChange(projectRoot, 'add-auth')，且 openspec/changes/ 不存在 那么（ THEN ） 系统创建完整路径，包括所有必要的父目录 场景：拒绝非法的 change 名称 当（ WHEN ） 使用非法名称调用 createChange(projectRoot, 'Add Auth') 那么（ THEN ） 系统抛出一个校验错误 需求：Change 名称校验（ Change Name Validation ）系统 必须（ SHALL ） 校验 change 名称符合 kebab-case 规范。场景：合法的 kebab-case 名称被接受 当（ WHEN ） 校验一个类似 add-user-auth 的名称 那么（ THEN ） 校验返回 { valid: true } 场景：允许数字后缀 当（ WHEN ） 校验一个类似 add-feature-2 的名称 那么（ THEN ） 校验返回 { valid: true } 场景：允许单个单词 当（ WHEN ） 校验一个类似 refactor 的名称 那么（ THEN ） 校验返回 { valid: true } 场景：拒绝大写字母 当（ WHEN ） 校验一个类似 Add-Auth 的名称 那么（ THEN ） 校验返回 { valid: false, error: "..." } 场景：拒绝空格 当（ WHEN ） 校验一个类似 add …

Galaxy比数平台功能介绍及实现原理｜得物技术
type: item
date: 2026-01-20T14:27:46+08:00
description: 一、背景得物经过10年发展，计算任务已超10万+，数据已经超200+PB，为了降低成本，计算引擎和存储资源需要从云平台迁移到得物自建平台，计算引擎从云平台Spark迁移到自建Apache Spark集群、存储从ODPS迁移到OSS。在迁移时，最关键的一点是需要保证迁移前后数据的一致性，同时为了更加高效地完成迁移工作（目前计算任务已超10万+，手动比数已是不可能），因此比数平台便应运而生。二、数据比对关键挑战与目标关键挑战一：如何更快地完成全文数据比对现状痛点：在前期迁移过程中，迁移同学需要手动join两张表来识别不一致数据，然后逐条、逐字段进行人工比对验证。这种方式在任务量较少时尚可应付，但当任务规模达到成千上万级别时，就无法实现并发快速分析。核心问题：效率瓶颈：每天需要完成数千任务的比对，累计待迁移任务达10万+，涉及表数十万张。扩展性不足：传统人工比对方式无法满足大规模并发处理需求。关键挑战二：如何精准定位异常数据现状痛点：迁移同学在识别出不一致数据后，需要通过肉眼观察来定位具体问题，经常导致视觉疲劳和分析效率低下。核心问题：分析困难：在比对不通过的情况下，比对人员需要人工分析失败原因。复杂度高：面对数据量庞大、加工逻辑复杂的场景，特别是在处理大JSON数据时，肉眼根本无法有效分辨差异。耗时严重：单次比对不通过场景的平均分析时间高达1.67小时/任务。比数核心目标基于以上挑战，数据比对系统需要实现以下核心目标：高并发处理能力：支持每天数千任务的快速比对，能够处理10万+待迁移任务和数十万张表的规模。自动化比对机制：实现全自动化的数据比对流程，减少人工干预，提升比对效率。智能差异定位：提供精准的差异定位能力，能够快速识别并高亮显示不一致的字段和数据。可视化分析界面：构建友好的可视化分析平台，支持大JSON数据的结构化展示和差异高亮。性能优化：将用户单次比对分析时间从小时级大幅缩短至分钟级别。可扩展架构：设计可水平扩展的系统架构，能够随着业务增长灵活扩容。三、解决方案实现原理快速完成全文数据比对方法比数方法调研待比对两表数据大小：300GB，计算资源：1000c经过调研分析比数平台采用第二种和第三种相结合的方式进行比数。先Union再分组数据一致性校验原理假如我们有如下a和b两表张需要进行数据比对表a：表b：表行数比较：select count(1) from a ;select count(1) from b ;针对上面的查询结果，如果数量不一致则退出比对，待修复后重新比数；数量一致则继续字段值比较。字段值比较：第一步：union a 和 bselect 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score` from a union all select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `age`, `score` from b第二步：sum(_t1_count)，sum(_t2_count) 后分组select sum(_t1_count) as sum_t1_count, sum(_t2_count) as sum_t2_count, `id`, `name`, `age`, `score` from ( select 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score` from a union all select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `age`, `score` from b ) as union_table group by `id`, `name`, `age`, `score`第三步：把不一致数据写入新的表中(即上面表中sum_t1_count和sum_t2_count不相等的数据)drop table if exists a_b_diff_20240908; create table a_b_diff_20240908 as select * from ( select sum(_t1_count) as sum_t1_count, sum(_t2_count) as sum_t2_count, `id`, `name`, `age`, `score` from ( select 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score` from a union all select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `ag…

AI Coding与单元测试的协同进化：从验证到驱动
type: item
date: 2026-01-19T21:55:46+08:00
description: AI生成代码质量难以把控！本文分享来自美团的技术实践，三大策略破解AI编程痛点。单测快速验证逻辑正确性，安全网保护存量代码演进，TDD模式精准传递需求。告别「看起来没问题」的错觉，构建AI时代的代码质量保障体系。一、引言目前，国内外很多AI Coding助手能在几秒钟内生成完整代码块，大大提升了开发效率，但这种高速开发模式也带来了潜在风险——与人工编码不同是，AI Coding助手生成代码存在两个特殊风险：其一，AI Coding助手依赖于上下文与模型自身的能力，输出的代码质量相对不可控。其二，AI生成的代码虽然逻辑通顺、结构完整，但可能隐藏着难以察觉的边界问题或逻辑缺陷。核心问题：我们如何快速的验证AI生成代码的质量和可靠性？本文旨在分享如何借助单元测试，让AI编程合作更高效可靠，主要解决三个常见痛点：肉眼审查困境：AI一次性生成大量代码时，难以快速准确判断逻辑完备性；存量代码信任危机：如何验证AI修改老代码时，不会产生非预期的结果；需求传达难题：如何精准向AI表达复杂需求并快速验证。针对上述三个常见痛点，本文提出采用不同的单元测试策略来应对以上问题。每个策略都针对一个特定痛点设计：策略一通过测试解决肉眼审查的局限性；策略二构建单测安全网应对存量代码的信任问题；策略三则采用TDD模式优化需求传达与验证流程。下文将依次展开说明，希望能对大家有所帮助或启发。二、策略一：单测检验AI代码逻辑正确性2.1 问题背景传统的人工代码审查在AI生成的大量代码面前显得低效且不可靠。在软件测试实践中，有着测试左移（Shift Left Testing）的概念，本质上是借助工具和测试手段更早地发现问题和预防问题。在AI Coding时代，这一理念尤为关键：跳过单元测试直接集成测试看似”抄近路”，实则是将风险后置——开发阶段几分钟能发现的Bug，在集成测试环境可能需要较长定位修复，这中间包含了代码部署、环境准备、测试条件的准备、问题定位、开发人员修复、再次部署验证等一系列漫长的环节。相比之下，单元测试具有独特的优势：它能够独立运行、快速验证结果，并且可以无限次重复执行。这种测试方式就像是为项目进行的一次性投资，却能为整个开发周期构建起一张可靠的“安全网”。它不仅能实时验证AI Coding生成的代码是否正确，更能持续保障未来代码的质量稳定性，让开发团队始终对代码库保持信心。2.2 案例：分页查询接口的隐蔽Bug任务背景：实现一个支持多条件筛选的复杂分页查询接口pageQueryRobotAI生成了如下核心查询逻辑：public List<AgentRobotE> pageQueryRobotsByCondition(List<Long> shopIds, String chatSceneCode, Boolean enabled, Integer pageNo, Integer pageSize) { // ... 前置校验代码 ... // 分页查询机器人基础信息 int offset = (pageNo - 1) * pageSize; List<AgentRobotEntity> entities = robotIds.stream() .skip(offset) .limit(pageSize) .map(robotId -> agentRobotDAO.getRobotById(robotId, false)) .filter(Objects::nonNull) // 问题代码：类型不匹配的隐蔽Bug .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled ? 1 : 0)) .filter(entity -> Objects.equals(entity.getChatSceneCode(), chatSceneCode)) .collect(Collectors.toList()); return entities.stream() .map(this::convertToModel) .filter(Objects::nonNull) .collect(Collectors.toList()); } 问题分析：这段代码看起来逻辑完整，但第8行的过滤逻辑包含了多个复杂元素：三元运算符 enabled ? 1 : 0Objects.equals 的使用Boolean到Integer的隐式逻辑转换仅凭肉眼很难发现其中的类型不匹配问题。单元测试发现问题：通过AI编写了17个全面的单元测试用例，覆盖：正常场景：各种有效参数组合边界场景：null值、空集合处理参数组合：enabled为true/false/null的不同情况@Test pu…

AI Coding与单元测试的协同进化：从验证到驱动
type: item
date: 2026-01-18T12:45:56+08:00
description: AI生成代码质量难以把控！本文分享来自美团的技术实践，三大策略破解AI编程痛点。单测快速验证逻辑正确性，安全网保护存量代码演进，TDD模式精准传递需求。告别「看起来没问题」的错觉，构建AI时代的代码质量保障体系。一、引言目前，国内外很多AI Coding助手能在几秒钟内生成完整代码块，大大提升了开发效率，但这种高速开发模式也带来了潜在风险——与人工编码不同是，AI Coding助手生成代码存在两个特殊风险：其一，AI Coding助手依赖于上下文与模型自身的能力，输出的代码质量相对不可控。其二，AI生成的代码虽然逻辑通顺、结构完整，但可能隐藏着难以察觉的边界问题或逻辑缺陷。核心问题：我们如何快速的验证AI生成代码的质量和可靠性？本文旨在分享如何借助单元测试，让AI编程合作更高效可靠，主要解决三个常见痛点：肉眼审查困境：AI一次性生成大量代码时，难以快速准确判断逻辑完备性；存量代码信任危机：如何验证AI修改老代码时，不会产生非预期的结果；需求传达难题：如何精准向AI表达复杂需求并快速验证。针对上述三个常见痛点，本文提出采用不同的单元测试策略来应对以上问题。每个策略都针对一个特定痛点设计：策略一通过测试解决肉眼审查的局限性；策略二构建单测安全网应对存量代码的信任问题；策略三则采用TDD模式优化需求传达与验证流程。下文将依次展开说明，希望能对大家有所帮助或启发。二、策略一：单测检验AI代码逻辑正确性2.1 问题背景传统的人工代码审查在AI生成的大量代码面前显得低效且不可靠。在软件测试实践中，有着测试左移（Shift Left Testing）的概念，本质上是借助工具和测试手段更早地发现问题和预防问题。在AI Coding时代，这一理念尤为关键：跳过单元测试直接集成测试看似”抄近路”，实则是将风险后置——开发阶段几分钟能发现的Bug，在集成测试环境可能需要较长定位修复，这中间包含了代码部署、环境准备、测试条件的准备、问题定位、开发人员修复、再次部署验证等一系列漫长的环节。相比之下，单元测试具有独特的优势：它能够独立运行、快速验证结果，并且可以无限次重复执行。这种测试方式就像是为项目进行的一次性投资，却能为整个开发周期构建起一张可靠的“安全网”。它不仅能实时验证AI Coding生成的代码是否正确，更能持续保障未来代码的质量稳定性，让开发团队始终对代码库保持信心。2.2 案例：分页查询接口的隐蔽Bug任务背景：实现一个支持多条件筛选的复杂分页查询接口pageQueryRobotAI生成了如下核心查询逻辑：public List<AgentRobotE> pageQueryRobotsByCondition(List<Long> shopIds, String chatSceneCode, Boolean enabled, Integer pageNo, Integer pageSize) { // ... 前置校验代码 ... // 分页查询机器人基础信息 int offset = (pageNo - 1) * pageSize; List<AgentRobotEntity> entities = robotIds.stream() .skip(offset) .limit(pageSize) .map(robotId -> agentRobotDAO.getRobotById(robotId, false)) .filter(Objects::nonNull) // 问题代码：类型不匹配的隐蔽Bug .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled ? 1 : 0)) .filter(entity -> Objects.equals(entity.getChatSceneCode(), chatSceneCode)) .collect(Collectors.toList()); return entities.stream() .map(this::convertToModel) .filter(Objects::nonNull) .collect(Collectors.toList()); } 问题分析：这段代码看起来逻辑完整，但第8行的过滤逻辑包含了多个复杂元素：三元运算符 enabled ? 1 : 0Objects.equals 的使用Boolean到Integer的隐式逻辑转换仅凭肉眼很难发现其中的类型不匹配问题。单元测试发现问题：通过AI编写了17个全面的单元测试用例，覆盖：正常场景：各种有效参数组合边界场景：null值、空集合处理参数组合：enabled为true/false/null的不同情况@Test pu…

Meta 运用基于大型语言模型的变异测试提升合规覆盖率
type: item
date: 2026-01-09T22:31:20+08:00
description: 为了提高其软件系统的合规覆盖率，Meta 已经将大型语言模型应用于变异测试。这种方法将 LLM 生成的变异体（mutants）和测试集成到 Meta 的自动化合规加固（ACH）系统中，消除了传统变异测试在可扩展性和准确性方面的限制。该系统的目标是在满足合规义务的同时保持产品和服务的安全，帮助团队更高效地满足全球监管要求。 变异测试是故意在代码中引入一些小的变异体，并检查测试是否能够检测到它们，以此来评估测试套件的有效性。由于变异体数量过多、计算成本高昂且存在价值有限的等效变异体等因素，传统编译测试的应用有限。Meta 的方法是利用大型语言模型生成具备上下文感知能力的变异体以及对应的测试，从而降低噪声并使工程工作聚焦于高价值代码路径。 在没有 LLM 指引之前，变异测试依赖于基于规则的静态操作符。这些操作符会无差别地生成大量的变异体，其中许多在语义上与原始代码等价，压跨了测试基础设施和开发流程。 Meta的ACH系统使用 LLM 生成恰当的变异体和有针对性的测试，重点关注隐私、安全和监管问题。基于LLM的等价检测器会过滤掉多余的变异体，而测试生成器会生成单元测试，工程师可以进行审查但不需要手动编写，这显著降低了运营开销。Facebook、Instagram、WhatsApp 和 Meta 的可穿戴平台的早期部署产生了数万个变异体和数百个可执行的测试。ACH 系统架构概览（图片来源：Meta技术博客） 自从将研究成果纳入 ACH 以来，Meta 在FSE 2025和EuroSTAR 2025大会上展示了他们的工作成果，即 LLM 如何帮助他们克服以前限制大规模变异测试的障碍。借助生成式 AI 更高效地生成测试用例，传统上用于评估测试质量的变异测试如今变得更具实用性和可扩展性。 正如 Meta 工程团队所强调的那样： 从 2024 年 10 月到 12 月，我们尝试在 Facebook、Instagram、WhatsApp 和 Meta 的可穿戴平台上部署了用于隐私测试的 ACH。在数千个变异体和生成的数百个测试中，隐私工程师接受了 73%的测试，其中 36%被判定为与隐私相关。 在 ACH 的基础上，Meta 推出了即时捕获测试（JiTTest）挑战赛，旨在探索大型语言模型在自动化软件测试中的应用。该系统会生成强化测试以防止回归问题，并生成捕获测试用于检测新代码或变更代码中的缺陷。它会在拉取请求进入生产环境前生成测试结果以供审核，这既解决了测试预言问题（Test Oracle Problem），又保留了人工监督环节。在 FSE 2025 大会上，Meta 发表了一篇论文，详细阐述了 JiTTest 挑战及其相关的开放研究课题。 Meta 表示，LLM 将耗时且容易出错的过程转变为更高效的系统，帮助简化并优化了合规和风险管理框架。正在进行的工作包括：将 ACH 扩展到隐私测试和 Kotlin 之外的更多领域和语言；通过微调和提示工程改进变异体生成；解决测试预言问题。Meta 还在研究开发人员如何与 LLM 生成的测试互动，以提升采用率和可用性。更多研究成果将在即将召开的会议中展示，包括Product@Scale。 https://www.infoq.com/news/2026/01/meta-llm-mutation-testing/

同时开 5 个智能体，把编程玩成了战略游戏
type: item
date: 2026-01-08T16:18:28+08:00
description: 整理 | 华卫 过去一周，工程界正反复剖析 Boris Cherny 在社交平台 X 上发布的一系列推文。Boris Cherny 是 Anthropic 公司 Claude Code 的创始人兼负责人，起初他只是随手分享个人终端配置，这条内容却演变成了一篇引爆行业的软件开发未来宣言，业内人士称其为这家初创公司发展历程中的 “分水岭时刻”。 开发者社区知名人士 Jeff Tang 写道：“作为程序员，若你还没研读这位 Claude Code 缔造者亲授的最佳实践，就已经落后了。” 另一位行业观察人士 Kyle McNease 则更进一步表示，凭借 Cherny 这次 “颠覆游戏规则的更新”，Anthropic 正 “火力全开”，或将迎来属于自己的 “ChatGPT 时刻”。同时开 5 个智能体，把编程玩成了战略游戏这份狂热源于一个看似矛盾的事实：Cherny 这套工作流异常简洁，却能让一名工程师发挥出小型工程团队的产出效能。有用户在 X 平台分享了实践这套工作流的感受，称其体验 “更像玩《星际争霸》”，而非传统编程。核心变化在于，开发者从敲代码语法转变为指挥自主协作的智能单元。 在 Cherny 的分享中，最令人震撼的一点在于：他从不采用线性模式编程。传统开发的 “核心循环” 流程是程序员编写一个函数、完成测试，再推进下一项任务。而 Cherny 却扮演着一支舰队指挥官的角色。 “我在终端里并行运行五个 Claude 智能体，把标签页按 1 到 5 编号，借助系统通知来判断哪个 Claude 需要输入指令。”Cherny 写道。通过调用 iTerm2 系统通知功能，Cherny 得以高效管理五条并行的工作流：一个智能体运行测试套件，另一个重构遗留模块，第三个则撰写文档。他还会在浏览器的 claude.ai 平台上同时运行 “5 到 10 个 Claude 智能体”，并通过 “传送” 指令，在网页端与本地设备之间切换任务会话。 Cherny 的另一个选择也出人意料：在这个极度追求低延迟的行业，他只使用 Anthropic 体量最大、运行速度最慢的模型 Opus 4.5。“我做任何任务都用开启思考模式的 Opus 4.5，它是我用过的最好用的编程模型。尽管它比 Sonnet 模型体积更大、速度更慢，但因为你需要对它的干预更少，而且它的工具调用能力更强，最终整体效率几乎总是比使用小型模型更高。”他解释道。 此外，Cherny 还详细介绍了他的团队如何解决 AI 的 “健忘症” 问题。标准的大语言模型在不同任务会话之间，无法 “记住” 某家公司特定的编程风格或架构决策。为解决这一难题，Cherny 的团队在代码仓库中维护着一个名为 CLAUDE.md 的共享文件。 “每当我们发现 Claude 执行任务出错，就把问题记录到 CLAUDE.md 里，这样 Claude 下次就不会再犯同样的错误了。” 他写道。这一做法让整个代码库变成了一个能够自我修正的有机体。当人类开发者审核代码合并请求、发现错误时，他们不仅会修正代码，还会标记相关问题，让 AI 更新自身的执行指令。 “每一次失误都能转化为一条规则。” 分析这一系列推文的产品负责人 Aakash Gupta 如此评价。 Cherny 公开工作流：极致自动化改造重复性任务业界对 Cherny 推文的热烈反响，标志着开发者对自身工作的认知正在发生关键性转变。长久以来，“AI 编程” 的定位不过是文本编辑器里的自动补全功能。而 Cherny 的实践证明，如今的 AI 已经可以成为驱动整个工作流程的 “操作系统”。 “我向 claude.ai/code 提交的每一处修改，都会通过 Claude 浏览器扩展程序完成自动测试。它会自动打开浏览器、测试用户界面，并反复迭代优化，直到代码正常运行，且用户体验达到预期标准。”Cherny 认为，无论是通过浏览器自动化、运行 Shell 命令，还是执行测试套件，赋予 AI 自主验证工作成果的能力能将最终产出质量提升 2~3 倍。智能体不只是编写代码，更能主动验证代码的有效性。 Cherny 借助斜杠指令（即已纳入项目代码库的自定义快捷指令），只需一次按键就能触发复杂操作流程。他重点介绍了一条名为 /commit-push-pr 的指令，这条指令他每天要调用数十次。无需手动输入 Git 命令、撰写提交说明、发起代码合并请求，智能体便能自主完成版本控制中的各项繁琐流程。 Cherny 还部署了子智能体来负责开发生命周期中的特定阶段。在核心开发工作完成后，他会启用代码简化智能体来优化架构；在正式发布任何内容之前，则会调用应用验证智能体执行端到端测试。 “如果你已是一名工程师，且渴望获得更强大的工作效能，一定要读读这篇分享。”Jeff Tang 在社交平台 X 上…