单元测试生成
选中函数或打开文件后,让 Cascade 一键生成完整的测试套件:
为 @src/utils/pricing.ts 中的 calculateDiscount 函数生成完整测试。
测试框架:Vitest + TypeScript
测试文件位置:src/utils/__tests__/pricing.test.ts
测试要求:
1. 正常路径:各种折扣类型(百分比、固定金额)
2. 边界情况:0 折扣、100% 折扣、折扣大于原价
3. 错误情况:负数价格、无效折扣类型、null 输入
4. 测试用例描述用中文
5. 每个测试用例有注释说明测试意图
生成后运行一次测试,如果有失败说明函数可能有 bug。
Cascade 生成的测试示例(针对一个典型的工具函数):
import { describe, it, expect } from 'vitest'
import { calculateDiscount } from '../pricing'
describe('calculateDiscount', () => {
describe('正常路径 - 百分比折扣', () => {
it('应该正确计算 10% 折扣', () => {
expect(calculateDiscount(100, { type: 'percent', value: 10 }))
.toBe(90)
})
it('应该正确计算 50% 折扣', () => {
expect(calculateDiscount(200, { type: 'percent', value: 50 }))
.toBe(100)
})
})
describe('正常路径 - 固定金额折扣', () => {
it('应该正确减去固定金额', () => {
expect(calculateDiscount(100, { type: 'fixed', value: 20 }))
.toBe(80)
})
})
describe('边界情况', () => {
it('0% 折扣应该返回原价', () => {
expect(calculateDiscount(100, { type: 'percent', value: 0 }))
.toBe(100)
})
it('固定金额大于原价时,最低返回 0(不能为负数)', () => {
expect(calculateDiscount(50, { type: 'fixed', value: 100 }))
.toBe(0)
})
})
describe('错误情况', () => {
it('负数原价应该抛出错误', () => {
expect(() =>
calculateDiscount(-100, { type: 'percent', value: 10 })
).toThrow('价格不能为负数')
})
it('无效折扣类型应该抛出错误', () => {
expect(() =>
calculateDiscount(100, { type: 'invalid' as any, value: 10 })
).toThrow('无效的折扣类型')
})
})
})
测试覆盖率分析
Cascade 不只会生成测试,还可以分析现有测试的覆盖率盲点:
运行测试覆盖率报告:npm run test:coverage
然后分析 @src/services/payment.ts 的覆盖率情况:
1. 哪些代码路径没有被测试覆盖?
2. 哪些分支(if/switch)的某些条件没有被触发?
3. 优先级最高的3个补充测试用例是什么(按业务风险排序)?
4. 生成这3个测试用例
Playwright E2E 测试生成
Cascade 结合 @Web 可以生成 Playwright E2E 测试,覆盖用户操作流程:
为我的 React 购物车功能生成 Playwright E2E 测试。
测试场景(按优先级):
1. 用户登录 → 浏览商品 → 加入购物车 → 结算
2. 购物车修改数量 → 价格实时更新
3. 优惠码输入(有效/无效码)
4. 支付失败的错误处理流程
测试文件:tests/e2e/cart.spec.ts
基础 URL:从 process.env.BASE_URL 读取
使用 Playwright 的 Page Object Model 模式,
创建 CartPage 和 CheckoutPage 两个 Page Object。
// Cascade 生成的 Playwright POM 示例(节选)
import { type Page, type Locator } from '@playwright/test'
export class CartPage {
readonly page: Page
readonly cartItems: Locator
readonly totalPrice: Locator
readonly checkoutButton: Locator
readonly couponInput: Locator
constructor(page: Page) {
this.page = page
this.cartItems = page.locator('[data-testid="cart-item"]')
this.totalPrice = page.locator('[data-testid="cart-total"]')
this.checkoutButton = page.getByRole('button', { name: '结算' })
this.couponInput = page.getByPlaceholder('输入优惠码')
}
async updateQuantity(productId: string, quantity: number) {
const item = this.page.locator(`[data-product-id="${productId}"]`)
await item.getByRole('spinbutton').fill(String(quantity))
await item.getByRole('spinbutton').press('Tab')
// 等待价格更新动画完成
await this.page.waitForSelector('[data-updating="false"]')
}
async applyCoupon(code: string) {
await this.couponInput.fill(code)
await this.page.getByRole('button', { name: '应用' }).click()
return this.page.locator('[data-testid="coupon-result"]')
}
}
JSDoc / TSDoc 文档生成
为现有代码批量添加文档注释,是 Cascade 的高效场景:
为 @src/services/notification.ts 中所有 exported 函数
添加完整的 TSDoc 注释,包括:
- 函数功能描述(一句话)
- @param 每个参数的名称、类型、描述
- @returns 返回值的描述
- @throws 可能抛出的错误
- @example 使用示例(1-2个)
注释用中文,保持与现有代码的缩进一致。
不要修改任何逻辑代码,只添加注释。
AI 代码审查 Checklist
把这个 Checklist 加入 .windsurfrules,让 Cascade 在每次生成代码后自动对照检查:
## AI 代码审查 Checklist(放入 .windsurfrules)
生成代码后,请自动检查以下项目并在输出末尾给出简短报告:
安全 (Security):
□ 没有在代码中硬编码任何密钥或密码
□ SQL 查询使用参数化(防 SQL 注入)
□ 用户输入已经过验证(zod/joi 等)
□ API 响应不会暴露内部错误信息
性能 (Performance):
□ 没有 N+1 数据库查询
□ 数据库查询有必要的索引(WHERE 字段)
□ 大数组操作使用流处理而非一次性加载
可维护性 (Maintainability):
□ 函数名清晰表达意图
□ 没有魔法数字(使用命名常量)
□ 复杂逻辑有注释
错误处理 (Error Handling):
□ 异步操作有 try/catch
□ 错误有有意义的错误消息
□ 不忽略 Promise rejection
测试生成的质量保证
AI 生成的测试需要审查以下几点:① Mock 是否过度(过度 Mock 的测试不能发现真实 bug)② 断言是否有意义(不要只断言 "toBeTruthy()")③ 边界情况是否真实(AI 有时会生成重复的边界情况)④ 测试独立性(测试间不应该共享可变状态)。一条有用的原则:好的测试在代码实现错误时应该失败,而不是永远通过。
本章小结
AI 测试生成最大的价值在于:把"写测试"的摩擦降到零,让开发者没有借口不写测试。Cascade 生成的测试质量取决于 Prompt 的具体程度——明确指定测试框架、文件位置、测试类别(正常/边界/错误)能显著提升质量。Playwright E2E 测试生成 + Page Object Model 是前端自动化测试的最佳实践。