前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8655
  • 自研研究 Agent 拦截 AI 编程幻觉:文档先行策略
  • 像物理学家一样剪枝 LLM:区块移除的伊辛模型优化
  • Mac mini上的AI开发新范式:OpenClaw与Codex实战
  • Cloudflare Python Workers 正式上线,可用纯 Python 开发边缘应用
  • 浏览器直接给 ESP32 烧录 Claude 写的宏,无需 IDE 或工具链
  • Google 发布 Agent 安全风险报告:5 万美元循环消耗与凭证窃取案例
  • 多 Agent 合规流水线:用 RAG + 自修正架构对抗 WCAG 幻觉问题
  • Anthropic 发布金融领域 Claude 参考智能体套件
  • OpenAI 披露强化学习模型在上下文压缩时插入 Prompt 注入
  • Jev 决策模型实测:0.3秒完成意图分类和工具路由,$0.00004/次
  • Kimi Code Desktop 上线:图形界面 + 内置终端 + Git 状态,支持 Swarm 多 Agent 协
  • StepFun Step 5 Preview:600B 总参数 MoE 模型,1M 超长上下文,10 月开源
  • JSON-Render:通吃 React/Vue/Svelte/React Native 等 10+ 框架的生成式 UI
  • Agent-Native:让 Agent 能力同时暴露给 LLM 工具调用和 UI 操作的 TypeScript 框架
  • 清华联合无问芯穹开源具身智能体RPent,GPT-6 Astra注入机器人
  • AI Agent工具调用边界case:路由错误比想象中更脆弱
  • AI按它能读的契约编程,而非你想要的
  • MCP 远程服务器实现 AI 驱动的确定性 UI 编排
  • 阶跃Step 5 Preview实测:27B参数开源模型冲至Top2
  • 用Responses API构建有边界的GPT-6 Astra Agent
  • 用破坏不变量法审查 AI 生成代码
  • AI 编程测试冻结:保存异常指纹而非测试名
  • 程序员亲历:全公司用 Claude Code 批量生产代码,没人读代码,12 小时工作制
  • 自托管Llama部署成本全解析:GPU之外容易被忽视的隐性开销
  • Builder.io开源Agent-Native框架:让人与AI共享同一操作层
  • 让AI编程代理在中断后从断点恢复:session化执行轨迹方案
  • CI如何验证AI代理真的跑了测试而不是伪造结果
  • llm-keys-ui:让Coding Agent安全获取API密钥的插件
  • AI产品定价数学:固定费率如何悄悄亏损
  • ZCode事件:AI编程工具静默上传全部Git历史
  • Anthropic自评:R&D自动化率26%,但完全自主为0
  • 阿里Qwen-Image-2.1:70亿参数开源图像生成拳打闭源模型
  • OWASP CRS 规则引擎:给 LLM 和 MCP 加上 WAF
  • 智谱 MaaS 上线数据不留存机制,可申请开通
  • 如何界定可完成的AI工程范围
  • Cursor中直接查询技术文档的MCP方案
  • AI Agent的过度自信陷阱
  • Cursor与.NET周报:七个实战规则
  • AI Agent失效?模型可能不是根源
  • Qwen-Image-2.1开源:7B参数兼顾生图与编辑
  • 阿里开源 Qwen-Image-2.1:7B 参数兼顾透明图生成与多图编辑
  • 免费模型Trace不能支持的五个评估主张
  • AI重构前的副作用冻结术:先录 Ledger 再动格式
  • Agent能改Oracle则Green Build不足为信:独立检查三原则
  • AI编程导致代码质量下降?根子在质量管理
  • AI连接数据库必须先脱敏:PII保护实战指南
  • Anthropic与埃森哲20亿美元共建AI安全评估体系
  • Copilot CLI恢复检查点导致1GB未跟踪文件被删
  • AI代码审查升级:结果直发PR评论,淘汰复制粘贴
  • Higgsfield:开源万亿参数模型分布式训练框架
  • LlamaIndex多Agent工作流:事件驱动共享状态编排
  • 已加载 51 / 8655
8.0
热点
AI SCORE
编程提效2026-09-21 09:54

用破坏不变量法审查 AI 生成代码

dev.to · AI#代码审查#AI编程#测试
Editor brief · 编辑速览

通过故意破坏代码不变量来验证测试有效性,可发现 AI 生成代码中测试未覆盖的逻辑漏洞。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

AI 助手返回了一个 diff 和配套的测试,所有测试都通过了。尴尬的时刻在于,你仍然无法用自己的话解释这些测试究竟在保护什么。

一种审查技巧是选择一个不变量,故意打破它,然后检查是否有测试失败。失败的预期会指向它在实现中保护的条件。

本文将 SquadNote 真实的通知路由器及现有测试提取到一个临时副本中。删除一个删除条件后,8 个通过的测试变成 7 个通过加 1 个失败。检查于 2026 年 9 月 11 日执行,使用 Node.js v24.15.0 和 Vitest 4.1.4。

这个实验的目的不是判断代码的作者身份。它展示的审查流程同样适用于从 AI 助手那里收到的代码。这里描述的是已验证过的流程,不声称持续使用会带来什么好处。

将"登出正常"转化为关于存储数据的条件

示例涉及删除设备的推送令牌。假设一个设备从账户 A 切换到账户 B,随后收到来自 A 的延迟注销请求。

"登出正常"这种表述留给了太多解读空间。这里的不变量是:

来自前所有者 A 的请求不得删除已转移到 B 的设备令牌。

这明确了执行者、目标和必须保留的数据。相比"正确处理授权",它更容易转化为测试。

相关的删除谓词是:

and(
  eq(pushTokens.userId, ctx.session.user.id),
  eq(pushTokens.token, input.token),
)

令牌必须匹配,且其当前所有者必须与会话用户相匹配。注册和所有权转移是一个更大的话题;本次审查聚焦于删除谓词。

在修改代码前先写下反例

从操作序列开始:

A 注册了 ios-1 和 android-1。

B 注册了 android-1,将该令牌的所有权转移给 B。

A 请求注销 android-1。

B 的 android-1 和 A 的 ios-1 必须保留。

现有测试已经遵循了这个序列。它在之后读取数据库行,而不是仅检查是否调用了 API。其最终预期是:

expect(await rows()).toEqual([
  { user_id: "user-b", token: "android-1", platform: "android" },
  { user_id: "user-a", token: "ios-1", platform: "ios" },
]);

rows() 从哪里读取也很重要。这些测试使用真实的路由器和 libSQL 测试数据库,外部 HTTP 被 mock 了。如果 unregisterPushToken 本身被替换为一个总是成功的 mock,这个测试就不会执行这个谓词。

仅删除用户条件

实验将提交 0cda1e8 提取到临时目录并运行了原始测试。然后仅在该副本中将谓词改为:

eq(pushTokens.token, input.token)

这是一个为了检验测试而注入的故障。这不是提议的生产变更。仅按令牌删除应该允许 A 的过期请求移除 B 的注册。

失败的测试是那个断言切换账户只转移该设备且前所有者无法删除它的测试。它对存储行的预期不再匹配。

一个已经失败的测试无法确立这种差异。一个阻止测试套件启动的语法错误也无法确立预期的不变量被检测到。这里,失败发生在测试的数据预期上。

实验脚本提取修复的提交,运行基准,移除条件,再次运行测试,且不修改原始仓库。假设源项目的依赖已安装,从文章仓库运行:

node experiments/article-stock-2026-09/mutation-check.mjs ../circle-hub-multi-device-push

如果测试仍然通过,需要检查什么

这个反例被检测到了。如果不同的变更导致测试套件仍然通过,先检查反例是否到达了目标代码,再考虑增加更多测试。

例如,一个总是提供用户 A 的 mock 无法建立到 B 的转移。仅仅检查成功响应而不在之后读取行的断言可能会漏掉过度删除。测试也可能执行了与你修改的路由器不同的路由器。

按顺序阅读输入设置、调用的函数、外部边界的 mock 和最终预期。一旦你确定了哪些组件实际运行,就添加缺失的反例。

这个流程确定了一个选定的测试能够检测到一个选定的故障。它不能证明不存在每个授权 bug、每个有问题的并发顺序,或对真实设备的投递失败。这个实验没有使用外部投递或物理设备。

当向 AI 助手请求解释时,"如果移除这个条件,哪些数据会消失,哪个预期会失败?"能产生一个可以与执行结果对比的答案。记录不变量、反例和实际失败的预期。这份记录帮助下一个审查者判断相同的条件是否可以在清理期间被移除。

对于进一步的操作,你可以考虑屏蔽此人或举报滥用。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
用Responses API构建有边界的GPT-6 Astra Agent
下一篇
AI 编程测试冻结:保存异常指纹而非测试名