##TraeCode的100种用法|我用 TraeCode 给一个三年没人敢动的老项目补全单元测试,覆盖率从 20% 飙到 85%

我是谁,以及我遇到了什么问题

我是 Java 后端开发,日常写业务接口、调中间件。我们组有个核心服务,上线三年多了,经历了五六个人接手,代码逻辑复杂得像一团乱麻。

最要命的是,这个项目的单元测试覆盖率只有 20% 左右,而且很多测试都是"假测试"——只测 happy path,稍微改点代码就挂。每次要重构或者加新功能,大家都提心吊胆,因为不知道改完之后会不会把别的地方搞崩。

上个月领导要求做一次大的架构升级,把一些老旧的依赖替换掉。但是没人敢动,因为没有测试兜底,改完不知道会不会出事。这个任务就落到了我头上。

我是怎么用 TraeCode 解决这件事的

我主要用的是 SOLO 模式,因为需要它自主分析整个项目结构,而不是只改某一个文件。

第一步:让 TraeCode 先理解项目

我把项目根目录打开,跟它说:“帮我分析一下这个项目的核心业务逻辑,找出哪些模块最需要补单元测试”。

它花了两分钟扫描了整个项目,然后给了我一个优先级列表:

  1. OrderService - 订单核心逻辑,调用链最深,覆盖率 15%
  2. PaymentProcessor - 支付处理,涉及第三方调用,覆盖率 8%
  3. InventoryManager - 库存管理,并发场景多,覆盖率 12%

它还指出了每个模块的关键方法和边界条件,比如 OrderService 里的 calculateTotalPrice 方法有 7 个分支判断,但现有测试只覆盖了 2 个。

第二步:让它生成测试用例

我选了 OrderService,跟它说:“给 calculateTotalPrice 方法生成完整的单元测试,覆盖所有分支条件,包括边界值和异常情况”。

它不仅生成了测试代码,还解释了每个测试用例的目的:

  • 测试正常订单(单个商品、多个商品)
  • 测试折扣计算(满减、折扣券、会员折扣叠加)
  • 测试边界值(0 元订单、超大金额订单)
  • 测试异常情况(商品不存在、价格字段为空)

第三步:处理 Mock 和依赖注入

老项目的依赖关系很乱,很多 Service 之间互相调用,还有直接 new 出来的对象。TraeCode 帮我用 Mockito 把这些依赖都 mock 掉了,还处理了 Spring 的依赖注入。

它甚至帮我写了一个测试基类,把通用的 mock 配置都抽出来了,后面的测试类直接继承就行。

第四步:运行测试并修复失败

跑起来之后有 3 个测试失败了。我把错误日志丢给它,它分析之后发现是测试数据的问题——有些测试用了不合理的输入(比如负数价格),导致业务逻辑抛异常。

它帮我调整了测试数据,并且加了一些防御性判断,确保测试不会因为脏数据挂掉。

第五步:覆盖率报告

最后让它生成了一份覆盖率报告。OrderService 的覆盖率从 15% 提升到了 82%,整个项目的覆盖率从 20% 提升到了 85%。

成果展示

我用了三天时间,把三个核心模块的测试都补全了:

  • OrderService:覆盖率 15% → 82%
  • PaymentProcessor:覆盖率 8% → 79%
  • InventoryManager:覆盖率 12% → 88%

整个项目的测试覆盖率从 20% 提升到了 85%。

更重要的是,这些测试不是"假测试"——它们真的能发现问题。上周有个同事改了一个折扣计算的逻辑,跑测试的时候直接挂了,避免了线上事故。

现在架构升级已经做完一半了,改完之后跑一遍测试就知道有没有破坏原有逻辑,心里踏实多了。

效率对比

以前怎么做

  • 先看代码,理解业务逻辑(半天)
  • 手写测试用例,想边界条件(一天)
  • 处理 mock 和依赖注入,各种报错(一天)
  • 总共:一个模块的测试要写 2-3 天

现在怎么做

  • 让 TraeCode 分析项目,找出需要测试的模块(10 分钟)
  • 让它生成测试代码,review 一下(30 分钟)
  • 处理失败的测试,调整数据(1 小时)
  • 总共:一个模块的测试半天就能搞定

效率提升:从 2-3 天缩短到半天,快了 4-6 倍。

经验和技巧总结

  1. 先给上下文,再让它动手:不要一上来就说"给我写测试",先让它理解项目结构和业务逻辑,这样生成的测试才有针对性。

  2. 分模块逐步推进:不要一次性让它给整个项目写测试,先挑一个核心模块,跑通了再换下一个。这样出了问题也容易定位。

  3. Review 很重要:TraeCode 生成的测试代码不一定完全正确,一定要自己过一遍。特别是边界条件和异常场景,要确认是否符合业务逻辑。

  4. 测试基类很有用:让它写一个测试基类,把通用的 mock 配置抽出来,后面的测试类直接继承,能省很多重复代码。

  5. 覆盖率不是目的:不要为了追求覆盖率而写测试,要写真正能发现问题的测试。有些分支可能永远走不到,但关键的边界条件一定要覆盖。

2 个赞

三天把覆盖率从 20 拉到 85,而且不是假测试——这贴是"老项目补测试正确姿势"的范本。你那句"先给上下文再让它动手"尤其关键,很多人一上来就说"写测试",结果生成一堆对不上的。我补一个你们下一步一定会用到的:把那几条核心链路(像 calculateTotalPrice 这种多分支的)锁成 CI 里的必跑回归集,以后谁改折扣逻辑、跑一遍挂了就拦住,比"覆盖率数字"实在得多。你提到同事改逻辑被测试拦下、避免线上事故,那正是测试该有的样子。测试基类抽出来这招也值得抄。

1 个赞

说到点上了,补完测试之后我第一件干的事就是把几条核心链路锁进CI回归集。现在每次提PR跑一遍,挂了直接拦住,比看覆盖率数字靠谱多了。之前有同事改折扣逻辑没跑全就提了,CI直接挂掉,省了一次线上事故。有测试兜底心里确实踏实。