推荐用 Mock Canvas 2D 上下文 + 行为断言或快照比对:Jest 用 jest-canvas-mock,Node.js 用 canvas 包;优先验证方法调用而非像素,必要时用 OffscreenCanvas 做像素快照;封装工具函数并清理绘图状态。

直接在真实 Canvas 上测试依赖绘图上下文的业务代码,既慢又难断言。推荐用 Mock Canvas 2D 上下文 + 快照比对 或 行为断言 的组合方式,兼顾可测性与可靠性。
用 canvas mock 库模拟 2D 上下文
真实 Canvas 无法在 Node.js 环境运行,浏览器中又难以隔离和断言绘制结果。用 canvas(Node.js)或 jest-canvas-mock(Jest)能创建可拦截、可检查的 mock ctx。
- Jest 用户:安装
jest-canvas-mock,它会自动 mockHTMLCanvasElement.prototype.getContext,返回一个带全部 2D 方法的 mock 对象 - Node.js 单元测试:用
canvas包创建真实但无渲染的 Canvas 实例,再调用getContext('2d')获取可用上下文 - 关键点:确保业务代码中不直接 new Canvas,而是通过
document.createElement('canvas')或传入的 canvas 元素获取 ctx,才便于 mock
断言绘图行为而非像素结果(推荐初阶)
比起截图比对,先验证「是否调用了预期方法」更稳定、易读、易调试。
- 用 Jest 的
jest.fn()包裹关键 ctx 方法,如ctx.fillRect = jest.fn() - 执行业务函数后,检查
ctx.fillRect.mock.calls是否包含期望参数,例如[[10, 20, 100, 50]] - 适合逻辑驱动型绘图:比如“数据大于阈值时画红框”,重点是分支是否触发对应绘图调用,不是颜色精度
用离屏 Canvas 做像素级快照比对(进阶)
当绘制效果必须精确(如图表坐标、字体排版、抗锯齿表现),可在浏览器环境用离屏 Canvas 渲染并提取 ImageData 比对。
立即学习“Java免费学习笔记(深入)”;
- 创建
offscreenCanvas = new OffscreenCanvas(200, 100),获取ctx = offscreenCanvas.getContext('2d') - 调用业务函数绘图,再用
ctx.getImageData(0, 0, w, h)获取像素数据 - 用
expect(imageData.data).toEqual(expectedData)断言;或转为 base64 后做快照(Jest 支持toMatchInlineSnapshot) - 注意:需固定字体、缩放、抗锯齿设置,否则跨环境像素可能微差;建议只对小区域(如图标、刻度)做快照
封装可复用的测试工具函数
避免每个测试都重复 setup mock 或创建 canvas,抽离成辅助函数提升可维护性。
- 写
createMockCanvas(width, height):返回带预设尺寸和已 mock ctx 的 canvas 元素 - 写
assertDrawn(ctx, method, expectedArgs):统一校验某方法是否按参数被调用一次 - 写
captureCanvas(canvas):统一处理 getImageData + 数据标准化(如忽略 alpha 通道变化)
不复杂但容易忽略:Canvas 绘图是状态机,测试前记得调用 ctx.resetTransform() 和 ctx.clearRect() 清理副作用,避免测试间相互污染。


















