AI 工具 | | 约 16 分钟 | 6,176 字

用 Trae 调试与测试:AI 辅助排错实战

利用 Trae 的 AI 能力快速定位 Bug、生成测试用例、提升代码质量

AI 辅助调试思路:从报错到根因

传统调试:报错 → Google → 翻 Stack Overflow → 试方案 → 不行 → 再试。Trae 把这个流程压缩了:

传统调试:报错 → Google → 翻文档 → 试方案 → 不行 → 再试 → 终于修好
Trae 调试:报错 → 丢给 AI → 分析根因 → 给出修复 → 搞定

但 AI 只是加速器,好的调试习惯依然重要。核心四步:

  1. 收集完整信息:报错信息、堆栈追踪、复现步骤
  2. 缩小范围:前端还是后端、逻辑错误还是类型错误
  3. 让 AI 分析:把信息喂给 Trae,让它定位根因
  4. 验证修复:AI 给的方案不一定对,跑测试确认

Chat 分析错误日志和堆栈

遇到报错,最直接的做法是把错误信息贴进 Chat,同时用 @file 引用相关代码:

@file:src/components/UserList.tsx

这个组件报了 TypeError: Cannot read properties of undefined (reading 'map'),
堆栈指向第 15 行。帮我分析根因,给出修复方案。

Trae 会结合文件内容和报错信息,告诉你数据还没加载完就调了 .map(),需要加空值检查。

多文件联合分析是 Trae 的强项。数据流跨了好几个文件时,一次引用多个文件:

@file:src/hooks/useUsers.ts
@file:src/components/UserList.tsx
@file:src/api/users.ts

用户列表偶尔白屏,帮我追踪数据从 API 到组件的完整链路。

Inline Edit 快速修复 Bug

Chat 分析完根因,按 Cmd + I 选中有问题的代码直接修。比如这段有 Bug 的代码:

function UserList({ data }) {
  return (
    <ul>
      {data.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}

选中后输入”添加空值保护,data 为空时显示加载状态”,Trae 直接生成修复:

function UserList({ data }) {
  if (!data) return <div className="loading">加载中...</div>;
  return (
    <ul>
      {data.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}

常见修复场景速查:

场景提示词写法效果
空值保护”添加 null/undefined 检查”自动加 guard clause
类型修复”修复类型错误,参数应该是 string[]“修正类型声明
逻辑修复”条件判断反了,应该是 >=“修正逻辑运算符
异步修复”这里缺少 await”补上 await 关键字
边界处理”处理数组为空的边界情况”添加 length 检查

Builder 批量修复类似问题

同一类 Bug 出现很多次?用 Builder 批量处理:

扫描 src/components 下所有组件,找出直接对 props 调用 .map()、.filter()
但没做空值检查的地方,统一添加防御性代码。
要求:用可选链或 guard clause,数据为空时显示 fallback UI。

Builder 自动扫描、逐个修复,你只需要在关键节点确认。批量修 ESLint 报错也一样好用:

项目有 47 个 ESLint 错误(no-unused-vars、prefer-const、no-explicit-any),
帮我批量修复。对于 no-explicit-any,根据上下文推断合适的类型。

AI 生成单元测试:Jest / Vitest 实战

调试是治标,测试才是治本。看一个完整的例子——被测函数:

// src/utils/price.ts
export function calculateDiscount(
  price: number,
  discountPercent: number,
  memberLevel: 'normal' | 'silver' | 'gold' | 'platinum'
): number {
  if (price < 0) throw new Error('Price cannot be negative');
  if (discountPercent < 0 || discountPercent > 100)
    throw new Error('Discount percent must be between 0 and 100');

  const multiplier = { normal: 1, silver: 1.05, gold: 1.1, platinum: 1.2 };
  const discount = price * (discountPercent / 100) * (multiplier[memberLevel] || 1);
  return Math.round((price - discount) * 100) / 100;
}

在 Chat 里输入 @file:src/utils/price.ts 用 Vitest 生成完整单元测试,覆盖正常、边界、异常,Trae 生成:

// src/utils/__tests__/price.test.ts
import { describe, it, expect } from 'vitest';
import { calculateDiscount } from '../price';

describe('calculateDiscount', () => {
  describe('基本折扣计算', () => {
    it('普通会员 10% 折扣', () => {
      expect(calculateDiscount(100, 10, 'normal')).toBe(90);
    });
    it('白金会员享受最大折扣', () => {
      expect(calculateDiscount(100, 10, 'platinum')).toBe(88);
    });
  });

  describe('边界值', () => {
    it('价格为 0', () => {
      expect(calculateDiscount(0, 50, 'normal')).toBe(0);
    });
    it('折扣为 100%', () => {
      expect(calculateDiscount(100, 100, 'normal')).toBe(0);
    });
  });

  describe('异常输入', () => {
    it('负数价格抛出错误', () => {
      expect(() => calculateDiscount(-10, 10, 'normal')).toThrow('Price cannot be negative');
    });
    it('折扣超过 100% 抛出错误', () => {
      expect(() => calculateDiscount(100, 150, 'normal')).toThrow('Discount percent must be between 0 and 100');
    });
  });
});

AI 生成集成测试与 E2E 测试

单元测试之外,Trae 也能写集成测试。引用路由和中间件文件,描述要覆盖的场景:

@file:src/server/routes/users.ts
@file:src/server/middleware/auth.ts

用 supertest 写集成测试:未登录返回 401、普通用户只能查自己、管理员查所有人。

E2E 测试用 Playwright,描述用户操作流程即可,Trae 会生成完整的页面交互测试代码。


测试覆盖率提升策略

不同项目类型的覆盖率目标参考:

项目类型行覆盖率分支覆盖率函数覆盖率
工具库 / SDK90%+85%+95%+
业务后端 API80%+75%+85%+
前端组件70%+65%+80%+
内部工具60%+50%+70%+

用 Trae 补测试的流程:先跑 npx vitest run --coverage,然后在 Chat 里引用覆盖率文件,让 AI 针对低覆盖率模块补测试。


实战:调试 TypeScript 类型错误

TypeScript 类型错误是最头疼的 Bug 之一。看这个有问题的 hook:

// src/hooks/useApi.ts — 有类型错误
function useApi<T>(url: string) {
  const [state, setState] = useState<{ data: T; error: string | null; loading: boolean }>({
    data: null,      // ❌ null 不能赋值给 T
    error: null,
    loading: true,
  });
  // ...
}

在 Chat 里让 Trae 修复,它会用可辨识联合类型重构:

type ApiState<T> =
  | { data: null; error: null; loading: true }
  | { data: T; error: null; loading: false }
  | { data: null; error: string; loading: false };

function useApi<T>(url: string): ApiState<T> {
  const [state, setState] = useState<ApiState<T>>({ data: null, error: null, loading: true });

  useEffect(() => {
    const controller = new AbortController();
    fetch(url, { signal: controller.signal })
      .then(res => res.ok ? res.json() as Promise<T> : Promise.reject(new Error(`HTTP ${res.status}`)))
      .then(data => setState({ data, error: null, loading: false }))
      .catch(err => err.name !== 'AbortError' && setState({ data: null, error: err.message, loading: false }));
    return () => controller.abort();
  }, [url]);

  return state;
}

调用方可以根据 loadingerror 自动收窄 data 的类型,不再需要手动断言。


实战:为现有代码补充测试用例

给老代码补测试是最常见的场景。假设有一个购物车服务:

// src/services/cart.ts
export class CartService {
  private items: CartItem[] = [];
  addItem(item: Omit<CartItem, 'quantity'>, quantity = 1): void { /* ... */ }
  removeItem(id: string): void { /* ... */ }
  updateQuantity(id: string, quantity: number): void { /* ... */ }
  getTotal(): number { /* ... */ }
  clear(): void { /* ... */ }
}

在 Chat 里引用文件,要求覆盖每个方法、边界情况和方法间交互,Trae 会生成包含添加、删除、数量更新、总价计算等完整测试。重点关注:重复添加累加数量、数量设为 0 自动删除、getItems() 返回副本不影响原数据这些容易遗漏的场景。


小结

层次能力对应模式
分析理解报错、追踪根因、解释堆栈Chat
修复快速修 Bug、类型修正、逻辑修正Inline Edit
预防生成测试、提升覆盖率、批量修复Builder

调试和测试是同一个质量保障闭环的两面。用 Trae 把这个闭环跑起来,代码质量会有质的提升。

调试是在已知的代码里寻找未知的错误,测试是在未知的场景里验证已知的逻辑。AI 不会替你思考该测什么,但它能帮你把”想到的”快速变成”跑得通的”。

评论

加载中...

相关文章

分享:

评论

加载中...