以测试为盾,重构为矛——老旧前端系统迭代中的“测试先行”实践总结

在耦合深、逻辑杂、文档少的老旧系统中,如何安全地向前走?我们用 Vitest + AI 辅助生成测试用例,构建了一套"以测试用例为验收标准"的迭代模式。

一、背景与困境

我们负责的业务模块是一个服役超过N年的前端系统,技术栈为 Vue3 + TypeScript。随着业务快速演进,代码逐渐暴露出典型的老旧系统特征:

  • 组件耦合深:父子组件通过多层 props 传递状态,兄弟组件共享全局 Store,改动一个组件往往"牵一发动全身"
  • 业务逻辑分散:部分逻辑在组件生命周期中,部分在自定义 Hook 中,还有一部分藏在工具函数里
  • 测试覆盖率近乎为零 :历史迭代追求速度,几乎没有单元测试,回归完全依赖人工 - 国内有一段时间是在推崇写单元测试, 但是薪资待遇没变, 事变多了, 工时没有增加, 基本很多团队是不太愿意做这个事情了
  • 文档缺失:业务规则只存在于少数核心开发者的记忆中
  • 测试用例不全: 人员变动, 测试用例可能只有某几次的版本,导致改动影响很困难。

每次需求迭代,开发人员都如履薄冰------改一行代码,不确定会影响到哪里

调试时间长, 测试范围模糊,不确定。

目前有遇到 嵌套 7-8层的 组件, 还有 组件之间各种传递大对象(50+字段)以上的。 调试的时候数据源复杂, 场景多变, 多个人员迭代, 参数传递越来越多, 实在是迭代不动。

单个模块代码爆炸 3000+ 行的逻辑。

二、破局思路:以测试用例驱动开发

我们引入的核心思想是:在修改业务代码之前,先为现有行为编写测试用例,让测试用例成为"安全网"和"行为说明书"。

有一些功能, 是人工就明显可以判别的 , 可以作为 背景梳理出来。 其他的已经是代码中存在的, 但是没有注释, 功能耦合严重的, 就依赖AI梳理。

具体工作流如下:

markdown 复制代码
1. 确定要修改的业务范围(某个组件 / 某个 Hook / 某个工具函数)
2. 将当前代码 + 相关依赖(props、store、外部接口)交给 AI
3. AI 辅助生成该模块的单元测试用例(Vitest)
4. 运行测试 ------ 此时测试应该全部通过(绿色)
5. 开始修改业务逻辑
6. 再次运行测试 ------ 如果变红,说明改动影响了预期行为,需要排查
7. 所有测试变绿后,提交代码

这个模式的核心价值在于:测试用例不是事后补充,而是事前锁定的"行为基线"

三、技术选型:Vitest

我们选择 Vitest 作为测试框架,原因如下:

特性 优势
与 Vite 生态无缝集成 项目已使用 Vite 构建,零配置成本
极快的执行速度 采用原生 ESM 和 SWC,测试反馈即时
Jest 兼容 API 学习成本低,describe / it / expect 语法通用
强大的 Mock 能力 vi.mock 轻松隔离外部依赖

四、AI 在流程中的角色:测试用例生成器

我们并没有让 AI 直接修改业务代码,而是将 AI 定位为 "测试用例辅助生成工具"

以某一个组件(最小单元) 为例, 将 某个组件要的 输入都 整理出来, 给 到AI, 提示词就是

复制代码
补充 xx 文件的 vitest测试用例, 根据我提供的测试数据, 如果场景是一致的, 列举一种场景即可。

前提是 vitest 都配置好了。 这个也比较简单。

特别是 某一个组件, 在多个入口场景被使用, 那么 就应该 明确列举一下

注意::大模型是有上下文限制的, 不要一次对多个模块补充测试用例, 最小单元去做测试用例补全。

  • 模块1-xx入口; props 入参数据
  • 模块2-xx入口; props 入参数据
  • 模块3-xx入口; props 入参数据

...

AI 生成测试用例的效果

维度 效果
覆盖度 覆盖正常路径、边界条件、异常情况
效率 从手动编写 30 分钟 → AI 生成 + 人工修正 5 分钟
质量 需人工校验边界条件和业务规则是否准确,AI 可能遗漏隐性规则
可读性 测试用例本身成为了"可执行的文档"

五、测试用例如何帮助我们安全迭代

场景一:重构组件内部逻辑

我们要将 OrderCard 中的状态判断逻辑抽取到一个自定义 Hook useOrderStatus 中。

  • 修改前:运行测试 → 全绿 ✅
  • 修改后:运行测试 → 如果变红 🔴,说明抽取逻辑时遗漏了某个分支条件
  • 修复:对比测试预期,补全逻辑,直到全绿

场景二:修改公共工具函数

formatPrice 原本只支持两位小数,新需求要支持三位小数。

  • 修改 formatPrice 后,所有依赖它的组件测试都会运行
  • 如果某个组件测试变红,说明该组件对金额格式有隐性依赖(比如只取两位显示)
  • 这提醒我们:要么修改组件适配新格式,要么在工具函数中做兼容处理

场景三:依赖升级或 API 变更

后端接口字段从 order_status 改为 status

  • 修改数据映射层后,跑一遍全量测试
  • 变红的测试精准指出哪些组件还在使用旧字段名
  • 相比人工排查,节省数小时

六、落地过程中的挑战与应对

挑战 应对策略
组件依赖过深,难以单独测试 使用 vi.mock 模拟子组件和 Store,聚焦当前单元
AI 生成的测试用例有误 人工 Review 并修正,逐步沉淀测试模板
测试环境与真实环境差异 补充集成测试,但单元测试仍作为第一道防线
团队不熟悉测试编写 AI 辅助降低门槛,但要求团队理解测试意图,而非盲目信任
测试执行时间变长 Vitest 的 watch 模式 + 只运行变更相关测试,保持反馈速度

小结

越是老旧系统, 人工维护的成本和精力越大。 在借助AI的帮助下, 思考这种场景如何破局。 从一上来先改代码的思维 变成 先补业务场景的边界, 再基于边界决定如何修改

我们后面对于复杂业务场景, 可能有2种比较好的选择

  • 基于当前的测试用例,打补丁,测试用例边界已经梳理清楚 (好迭代的场景,或者打补丁的代价和代码的复杂度不大), 可直接 给AI 投喂准确的需求, 迭代
  • AI 结合测试用例,发现这个 模块 (方法, 组件,接口) 不适用了, 直接将某个模块可以 copy一份, 将不要的逻辑删除, 再进行迭代,可能开发成本+测试成本更低,影响范围更小。

系统越是庞大, 越是老旧, 越是依赖人口口相传的地方, 基于这套方式的实践,在下一次迭代的意义越是明显。

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端