做图形编辑器开发的兄弟们,是不是还在为 Canvas 交互测试头秃?明明功能写完了,写测试却要花双倍时间模拟鼠标点击、拖拽和状态断言。write-unit-tests 这个 Skill 简直是救命稻草!它专门针对 tldraw SDK 的测试场景优化,能帮你秒生成符合 Vitest 标准的高质量测试代码,甚至连复杂的 Undo/Redo 逻辑都能一键搞定。🚀
核心功能
这个 Agent 不仅仅是简单的代码补全,它深刻理解 tldraw 的测试架构:
- 智能环境搭建:自动区分使用
TestEditor(集成测试)还是原生Editor(底层配置测试),并生成标准的beforeEach/afterEach生命周期代码。 - 交互模拟神器:一键生成
pointerDown,pointerMove,click,doubleClick等复杂的指针事件代码,支持精确到像素和 Handle(手柄)级别的操作。 - 状态与形状断言:不再需要手动写复杂的对象匹配,自动生成
expectShapeToMatch和expectToBeIn等专用断言,精准验证形状属性和编辑器状态机。 - Vitest 深度集成:完美支持
vi.spyOn进行方法 Mock,以及使用vi.useFakeTimers处理动画和时间依赖逻辑。
适用平台
该 Skill 完美适配主流 AI 编程助手,包括 Cursor, GitHub Copilot, Claude Code, OpenAI Codex, Gemini Code Assist, 文心快码, 腾讯云 CodeBuddy, 华为云 CodeArts 等。它能作为这些 IDE 的“最强外挂”,让 AI 准确理解 tldraw 的测试上下文,不再胡乱生成通用的 Jest 代码,而是生成真正可运行的图形化测试逻辑。
实操代码示例
想测试一个“选中并删除形状”的逻辑?看看它生成的代码有多干净:
import { createShapeId } from '@tldraw/editor';
import { TestEditor } from './TestEditor';
let editor: TestEditor;
beforeEach(() => {
editor = new TestEditor();
// 自动清理并初始化形状
editor.selectAll().deleteShapes(editor.getSelectedShapeIds());
editor.createShapes([
{ id: createShapeId('box1'), type: 'geo', x: 100, y: 100, props: { w: 100, h: 100 } }
]);
});
afterEach(() => {
editor?.dispose();
});
it('should select and delete a shape', () => {
const id = createShapeId('box1');
// 模拟鼠标点击选中
editor.click(150, 150, id);
// 断言状态
editor.expectToBeIn('select.idle');
expect(editor.getSelectedShapeIds()).toMatchObject([id]);
// 执行删除
editor.deleteShapes([id]);
expect(editor.getShape(id)).toBeUndefined();
});
优势分析
相比于通用的测试生成工具,write-unit-tests 的优势在于“懂行”:
- 上下文感知:它知道
packages/editor和packages/tldraw目录下应该运行不同的测试策略。 - 类型安全:生成的代码严格遵循 TypeScript 泛型规范,避免
@ts-expect-error满天飞的尴尬。 - 解决浮点数痛点:针对图形学中常见的精度问题,自动建议使用
toCloselyMatchObject进行模糊匹配。
应用场景
- 自定义形状测试:当你开发了一个新的
CustomShape,用它快速生成几何计算(Geometry)和渲染逻辑的单元测试。 - 工具行为验证:测试自定义 Tool(如画笔、连线)在不同鼠标事件序列下的状态切换是否正确。
- 复杂的撤销重做:验证在经过一系列修改操作后,
undo()和redo()是否能将画布完美还原到上一状态。
最佳实践
为了让测试代码更稳健,建议遵循以下规范:
- ID 管理:始终使用
createShapeId('name')来管理形状 ID,保持测试数据的可读性。 - 资源清理:务必在
afterEach中调用editor?.dispose(),防止内存泄漏影响后续测试运行。 - 时间控制:涉及动画或节流(Throttle)逻辑时,必须配合
vi.advanceTimersByTime()使用,不要依赖真实的setTimeout。
Canvas 应用的测试一直是个大坑,但有了这个工具,确实能少掉很多头发。为了更好地管理和复用这些高效的测试配置,建议使用 Skill优仓 获取更多 tldraw 相关的开发资源和智能体 Skill,让你的图形编辑器开发效率直接起飞!🌟
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END









暂无评论内容