跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言VScodeNode.jsAIjava

Copilot、Cursor、JetBrains 实战四场景:从测试到 CRUD 的关键写法

围绕生成测试、解释遗留代码、代码重构和生成 CRUD 四类场景,对比 GitHub Copilot、Cursor 和 JetBrains AI Assistant 的实际操作差异。强调提示词的写法是关键:测试时必须明确列出边界用例,解释代码需引导深入分析,重构前务必有测试兜底,生成 CRUD 要精确指定技术栈。结合各工具特点给出具体示例和注意点,指出 AI 处理重复工作,但业务逻辑与质量审查仍需开发者主导。

日志猎手发布于 2026/6/30更新于 2026/8/2018 浏览
Copilot、Cursor、JetBrains 实战四场景:从测试到 CRUD 的关键写法

Copilot、Cursor、JetBrains 实战四场景:从测试到 CRUD 的关键写法

这三款 AI 编程助手——GitHub Copilot、Cursor 和 JetBrains AI Assistant——用熟了都能扛掉不少重复工作,但各自擅长的场景不太一样。下面四个场景是我在实际项目里最常碰到的,每个工具的操作要点和坑也一并说清楚。提示词怎么写、哪些事得自己兜底,直接影响生成质量。

一、生成测试用例:覆盖边界是关键

让 AI 写测试,最容易踩的坑就是边界覆盖不全。你得在提示里把极端情况列清楚,它才会认真处理。下面分工具说。

GitHub Copilot

写测试时,Copilot 靠注释来理解意图。比如 divide 函数,只写 # test divide,它大概率只生成正常除法。在注释里明确列出边界场景——除数为 0、极小浮点、被除数为 0——生成的质量就明显提升。

def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

# 测试 divide 函数,包括正常情况、除数为 0、除数为极小值、被除数为 0 等边界情况
def test_divide():
    # 正常情况
    assert divide(10, 2) == 5.0
    # 边界情况 1:除数为 0,应抛出异常
    try:
        divide(10, 0)
        assert False, "Expected ValueError"
    except ValueError:
        pass
    # 边界情况 2:除数为极小值(接近 0 的浮点数)
    assert abs(divide(1, 1e-10) - 1e10) < 1e-5
    # 边界情况 3:被除数为 0
    assert divide(0, 5) == 0.0

如果生成还不全,就继续补注释,比如再加 # 测试负数除法,Copilot 会接着补上。

JetBrains AI Assistant

在 PyCharm 或 IntelliJ 里,右键点函数选 AI Assistant → Generate Tests,对话框里一定要把要求写死。默认生成往往只覆盖最常规的路径,不加这步很容易漏掉异常和极值。

提示词示例:

生成 JUnit 5 测试类,覆盖以下场景:

  1. 正常整数除法(10/2)
  2. 除数为 0(期望抛出 ArithmeticException)
  3. 除数为极小浮点数(1e-10)
  4. 被除数为最大值(Double.MAX_VALUE)
  5. 除数为负数(-2)

它会生成类似下面的代码:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {
    @Test
    void testNormalDivision() {
        assertEquals(5.0, Calculator.divide(10, 2));
    }
    @Test
    void testDivideByZero() {
        assertThrows(ArithmeticException.class, () -> Calculator.divide(10, 0));
    }
    @Test
    void testDivideByVerySmallNumber() {
        assertEquals(1e10, Calculator.divide(1, 1e-10), 1e-5);
    }
}

业务特有的边界(比如年龄不能为负)它猜不到,生成后得自己补上。

Cursor

Cursor 的聊天面板很适合自然语言交互。直接说明方法名、框架和边界要求,它会输出完整测试套件。例如:

为 UserService.createUser 方法生成 Jest 测试,用例要求:

  • 正常创建(姓名、邮箱有效)
  • 邮箱格式错误(应抛出 ValidationError)
  • 姓名超过 50 字符(边界测试)
  • 空对象传入(边界测试)

生成结果可以直接运行,但需要注意:Cursor 有时会使用过时的断言风格,如果与项目配置不符,手动改一下就好。

// userService.test.js
import { createUser } from './userService';

test('正常创建用户', () => {
    const user = createUser({ name: '张三', email: '[email protected]' });
    expect(user.id).toBeDefined();
});

test('邮箱格式错误', () => {
    expect(() => createUser({ name: '李四', email: 'invalid' }))
        .toThrow('ValidationError');
});

test('姓名超过 50 字符', () => {
    const longName = 'a'.repeat(51);
    expect(() => createUser({ name: longName, email: '[email protected]' }))
        .toThrow('Name too long');
});

二、解释遗留代码:别只问'这是啥'

遗留代码通常没注释、逻辑扭成一团。简单让 AI'解释这段代码',得到的往往是表面翻译,价值不大。得引导它做具体分析。

GitHub Copilot

结构化注释能大幅提升解释深度。在代码上方加一段类似这样的说明,Copilot 就会按点回答:

# 请逐行解释该函数的逻辑,重点说明:
# 1. 输入参数的作用和约束
# 2. 关键算法(如状态机、递归)
# 3. 可能的边界条件和 Bug 风险
# 4. 与其他模块的交互(如全局变量、外部调用)
def legacy_calculator(x, y, op):
    if op == 'add':
        return x + y
    elif op == 'sub':
        if x < y:
            # 遗留代码中常见的反直觉逻辑
            return 0 - (x - y)
        return x - y
    else:
        return None

它会详细指出 0 - (x - y) 实际就是 y - x,很可能是历史补丁的残留;还会提醒浮点比较的风险。这种提示远比自己盯着代码猜高效。

JetBrains AI Assistant

选中代码块,右键选择 Explain Code,默认给出的是基础解释。想挖深一点,得在面板里追加提问,比如:

请分析该函数的时间复杂度,并指出潜在性能瓶颈。同时说明如果要重构为异步逻辑,哪些部分需要修改。

AI 会输出类似下面的分析:

时间复杂度:O(n²),因为有两层嵌套循环。 瓶颈点:内层循环可改用 Map 查找降至 O(n)。 重构注意:第 20 行的 data.get(i) 可能返回 null,异步化前需统一处理。

这种交互式追问比一次性生成有用得多。

Cursor

Cursor 支持多轮对话,特别适合拆解复杂逻辑。我习惯这样问:

  • 第一轮:用一句话总结该函数的目的。
  • 第二轮:用 Mermaid 画出流程图。
  • 第三轮:flag 变量什么时候被重置?生命周期是怎样的?

解释结果还能直接导出为 Markdown 文档,团队分享很方便。

三、代码重构与优化:先有测试,再信任 AI

AI 重构常犯两个毛病:过度优化(删掉重要日志或注释),或悄悄改变行为。我的原则是:没有测试就不重构,生成后立刻跑测试看行为是否一致。

GitHub Copilot

在代码上方写目标明确的注释,Copilot 会按指令改。比如:

// 重构该函数:
// 1. 将 SQL 查询提取为独立方法
// 2. 使用 Stream API 替代 for-loop
// 3. 添加空数据检查,避免 NPE
// 4. 保持原有接口不变
public List<User> getActiveUsers(List<User> allUsers) {
    List<User> active = new ArrayList<>();
    for (User u : allUsers) {
        if (u.getStatus().equals("active")) {
            active.add(u);
        }
    }
    String sql = "SELECT * FROM users WHERE status = 'active'";
    // ... 执行 SQL(实际上这段逻辑冗余,仅为示例)
    return active;
}

生成的代码会提取 SQL 方法、用 Stream 筛选,并加上 null 检查:

public List<User> getActiveUsers(List<User> allUsers) {
    if (allUsers == null) return Collections.emptyList();
    String activeSql = getActiveUsersSql();
    return allUsers.stream()
        .filter(u -> "active".equals(u.getStatus()))
        .collect(Collectors.toList());
}
private String getActiveUsersSql() {
    return "SELECT * FROM users WHERE status = 'active'";
}

注意:Stream 在大数据量下不一定比 for-loop 快,如果性能敏感,最好做个对比。

JetBrains AI Assistant

选中代码,右键 → Refactor This Code,在提示框里把重构目标写具体:

目标:

  • 将循环替换为 Java Stream
  • 提取 validateInput 方法,处理 null 和空集合
  • 移除未使用的变量 legacyFlag
  • 保持原有异常抛出逻辑

AI 会生成 diff 预览,确认后再点 Apply 直接修改。但一定要先备份或提交到 Git,它的撤销机制有时不够利索。

Cursor

光标建议在临时分支上操作。在 AI Chat 输入:

请重构 processData 函数:

  • 将 for 循环改为 Promise.all(异步化)
  • 使用 TypeScript 类型注解
  • 限制并发数为 5(避免 DDoS)
  • 输出重构前后对比

它会给出带类型的重构版本,并且标注限制并发的实现(比如嵌入 p-limit):

// 重构前
async function processData(items) {
    const results = [];
    for (const item of items) {
        results.push(await fetchData(item));
    }
    return results;
}

// 重构后(限并发 + 类型)
async function processData<T>(items: T[]): Promise<ReturnType<typeof fetchData>[]> {
    const limit = pLimit(5);
    const limitedFetch = items.map(item => () => fetchData(item));
    return await Promise.all(limitedFetch.map(fn => limit(fn)));
}

之后跑一下性能测试,避免并发引入的问题。

四、用自然语言生成 CRUD 脚手架

生成 CRUD 时,AI 最怕的是把框架搞错。提示里必须声明技术栈和具体约束,否则它可能给你 Django 版本却要求 Spring Boot。我的习惯是:先生成最基础的增删改查,通过测试后再一层层加业务校验和权限。

GitHub Copilot

新建文件,用注释描述需求,Copilot 能实时补全。比如 FastAPI + SQLAlchemy 的例子:

# 使用 FastAPI + SQLAlchemy 生成 User CRUD:
# - 数据库表:users(id, username, email, created_at)
# - 包含:创建、查询单个、查询所有、更新、删除
# - 验证:username 长度 3-20,email 必须包含 @
# - 返回 JSON,包含状态码和消息

Copilot 会生成完整的模型、Pydantic 校验和路由。拿到代码后,再手动补上用户名唯一性检查这样的业务逻辑:

@app.post("/users/", response_model=User)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
    existing = db.query(UserModel).filter(UserModel.username == user.username).first()
    if existing:
        raise HTTPException(status_code=400, detail="用户名已存在")
    db_user = UserModel(username=user.username, email=user.email)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

JetBrains AI Assistant

在 Spring Boot 项目中,右键选 Generate Code from Description,写明要求:

使用 Spring Boot + JPA 生成 Product 资源的 CRUD REST API。 数据库表:products(id, name, price, stock, created_at) 要求:使用 Lombok 简化代码,添加全局异常处理,Swagger 文档支持,不生成测试代码。

它会自动生成实体类、Repository、Controller 和异常处理器骨架。之后再往 updateProduct 里加库存不能为负的校验:

if (dto.getStock() != null && dto.getStock() < 0) {
    throw new IllegalArgumentException("库存不能为负数");
}

Cursor

可以把需求写成 prompt.txt 放在项目根目录,然后让 AI 生成代码。例如 Node.js + Express + Mongoose 的 Category 模块:

项目:Node.js + Express + Mongoose
实体:Category(分类)
字段:_id, name, description, is_active, created_at
需求:
- 生成完整 CRUD 路由(/api/categories)
- 使用 async/await
- 添加分页查询(页码、每页数量)
- 返回格式:{ code: 0, data: {...}, msg: '成功' }
- 不包含认证

Cursor 会按 MVC 结构生成文件。拿到基础代码后,再在 updateCategory 里插入权限判断(假设已有认证中间件):

exports.updateCategory = async (req, res) => {
    if (!req.user || req.user.role !== 'admin') {
        return res.status(403).json({ code: -1, msg: '无权限操作' });
    }
    // ... 原有更新逻辑
};

几点实操心得

  1. 明确技术栈是第一原则
    每次生成前,把框架、语言、版本写清楚。AI 默认常用版本可能偏旧,不写就会给你惊喜。

  2. 迭代,别指望一次完美
    先让 AI 出基础版 → 测试 → 补提示 → 重新生成。三四个来回很正常。

  3. 测试自己补
    AI 生成的代码即使通过了简单用例,边界 bug 也常有。每个 CRUD 操作都得有自己的边界测试,参考第一节的方法。

  4. 审查不能省
    像审查同事代码一样查 AI 输出:SQL 注入风险、权限缺失、异常处理是否合理。

  5. Prompt 存下来
    把有效的提示词记录到项目 PROMPTS.md,团队后来者直接复用,效率高很多。

这三个工具,Copilot 擅长实时补全和逐步引导修改,Cursor 的交互式提问在拆解遗留代码或复杂逻辑时很舒服,JetBrains 则强在 IDE 深度集成,一键生成测试、重构和脚手架最省事。组合使用效果更好,比如用 JetBrains 生成基础代码,切到 Copilot 优化注释和片段,最后在 Cursor 里生成测试和文档。

说到底,AI 处理的是重复性、低价值的搭建工作,业务逻辑、架构决策和最终的质量兜底,还是得留给自己。

目录

  1. Copilot、Cursor、JetBrains 实战四场景:从测试到 CRUD 的关键写法
  2. 一、生成测试用例:覆盖边界是关键
  3. GitHub Copilot
  4. 测试 divide 函数,包括正常情况、除数为 0、除数为极小值、被除数为 0 等边界情况
  5. JetBrains AI Assistant
  6. Cursor
  7. 二、解释遗留代码:别只问“这是啥”
  8. GitHub Copilot
  9. 请逐行解释该函数的逻辑,重点说明:
  10. 1. 输入参数的作用和约束
  11. 2. 关键算法(如状态机、递归)
  12. 3. 可能的边界条件和 Bug 风险
  13. 4. 与其他模块的交互(如全局变量、外部调用)
  14. JetBrains AI Assistant
  15. Cursor
  16. 三、代码重构与优化:先有测试,再信任 AI
  17. GitHub Copilot
  18. JetBrains AI Assistant
  19. Cursor
  20. 四、用自然语言生成 CRUD 脚手架
  21. GitHub Copilot
  22. 使用 FastAPI + SQLAlchemy 生成 User CRUD:
  23. - 数据库表:users(id, username, email, created_at)
  24. - 包含:创建、查询单个、查询所有、更新、删除
  25. - 验证:username 长度 3-20,email 必须包含 @
  26. - 返回 JSON,包含状态码和消息
  27. JetBrains AI Assistant
  28. Cursor
  29. 几点实操心得
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 大模型前沿研究速递:16篇近期值得关注的论文
  • 昇腾平台 DeepSeek-R1 与 Qwen2.5 RL 训练优化及 cann-recipes-train 仓库解析
  • Flutter 应用架构从入门到可扩展的演进实践
  • 昇腾 NPU 部署 Llama 2 模型:性能测试与实战优化
  • 无人机避障算法核心技术:五种主流算法原理与实战应用场景
  • WhisperLiveKit 会议纪要模板定制:适配不同场景
  • 量化交易中 Python 与 C++ 的选择考量
  • ClawdBot 语音翻译:Whisper tiny 带口音英语与粤语 WER 对比
  • C++ 网络模块兼容性优化的 7 个关键步骤
  • Z-Image-ComfyUI 本地部署与中文提示词实战
  • AI 大模型在政务领域的落地应用与案例分析
  • 计算机网络:WebSocket 如何实现全双工通信
  • 使用 LangChain4J 实现 Agent 与 Tool 调用
  • OpenClaw 多飞书机器人配置与绑定指南
  • 医疗连续体机器人模块化控制界面设计与 Python 库应用
  • NOTEBOOKLM 新手教程:快速上手 AI 笔记工具
  • 从零开始实现 LLaMa3 模型:核心架构与代码解析
  • MATLAB 实现基于强制导向函数法(PFA)的无人机三维路径规划
  • Git 查看 Commit 修改文件概要的常用命令与技巧
  • RAG 评估指南:解析评估指标与代码示例

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online