使用 Jest 的 canvas 元素的简单测试示例
Posted
技术标签:
【中文标题】使用 Jest 的 canvas 元素的简单测试示例【英文标题】:Simple testing example of canvas element using Jest 【发布时间】:2021-06-20 23:48:57 【问题描述】:我正在尝试为此沙箱中的示例创建一个笑话测试: https://codesandbox.io/s/r3f-basic-demo-forked-297k3?file=/src/App.js
基本上我想在每个盒子上测试 onClick 功能。我已经遇到了开玩笑测试不在真正的浏览器中运行的事实。 Jest 使用 jsdom 来模拟 DOM 的必要部分。因此,我可能需要 jsdom 的 canvas 支持,但我不太确定该怎么做。
App.js
import React, useRef, useState from 'react'
import Canvas, useFrame from 'react-three-fiber'
function Box(props)
// This reference will give us direct access to the mesh
const mesh = useRef()
// Set up state for the hovered and active state
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
// Rotate mesh every frame, this is outside of React without overhead
useFrame(() =>
mesh.current.rotation.x = mesh.current.rotation.y += 0.01
)
return (
<mesh
...props
ref=mesh
scale=active ? [1.5, 1.5, 1.5] : [1, 1, 1]
onClick=(e) => setActive(!active)
onPointerOver=(e) => setHover(true)
onPointerOut=(e) => setHover(false)>
<boxBufferGeometry args=[1, 1, 1] />
<meshStandardMaterial color=hovered ? 'hotpink' : 'orange' />
</mesh>
)
export const App = () =>
return (
<>
<Canvas>
<ambientLight intensity=0.5 />
<spotLight position=[10, 10, 10] angle=0.15 penumbra=1 />
<pointLight position=[-10, -10, -10] />
<Box position=[-1.2, 0, 0] />
<Box position=[1.2, 0, 0] />
</Canvas>
</>
)
【问题讨论】:
一个经典的 *** 时刻,我找到了与我相同的问题,但没有答案。你能得到答案吗? 【参考方案1】:这不是一个很好的答案,但我发现这篇文章很有用:https://www.valentinog.com/blog/canvas/。
建议是为了正确测试 canvas
元素,不应该使用 Jest(或任何单元测试),而是使用某种 e2e 测试,以便它可以实际呈现 canvas
。
我能够通过以下方式进行一些较小的测试:
首先使用 jest 正常渲染您的页面。你可以给你的画布一个 test-id 或者(在我的例子中)在你的画布周围放一个 div 并给 div 一个 test-id。
我最终得到了以下结果:
let canvasContainer = getByTestId("canvas-container");
let canvas = canvasContainer.getElementsByTagName("canvas")[0];
let canvasContext = canvas.getContext("2d");
无论哪种情况,您的目标都是获取 canvas
' 元素上下文。
从那里你可以用canvasContext.__getDrawCalls()
检查它
这将为您提供有关迄今为止已完成的所有“drawCalls
”的一些信息(例如绘制线条或矩形或您有什么)。
需要对__getDrawCalls
进行一些检查,但您应该会发现到目前为止的每个呼叫都包含在内。
我写了一些函数来帮助我得到我想要的确切细节:
const getLineInfo = (lineInfo) =>
if (lineInfo.type !== "stroke")
return "not a line";
let lineInfoDetail = lineInfo.props.path[3];
return
lineStart:
x: lineInfoDetail.transform[4],
y: lineInfoDetail.transform[5],
,
lineEnd:
x: lineInfoDetail.transform[4] + lineInfoDetail.props.x,
y: lineInfoDetail.transform[5] + lineInfoDetail.props.y,
,
;
;
const getRectInfo = (rectInfo) =>
if (rectInfo.type !== "fill")
return "not a rect";
let rectInfoDetail = rectInfo.props.path[1];
return
rectStart:
x: rectInfoDetail.transform[4],
y: rectInfoDetail.transform[5],
,
rectEnd:
x: rectInfoDetail.transform[4] + rectInfoDetail.props.width,
y: rectInfoDetail.transform[5] + rectInfoDetail.props.height,
,
;
;
例如,如果我知道第二次绘制是一条线,我可以执行以下操作:
expect(getLineInfo(canvasContext.__getDrawCalls()[1])).toStrictEqual(
lineStart: x: 150, y: 250 ,
lineEnd: x: 150, y: 350 ,
);
这是测试该元素是否为起点为 x: 150, y: 250
和终点为 x: 150, y: 350
的线
但问题在于 您无法在 jest 中触发画布元素的单击和拖动事件,因此使用 jest 测试画布似乎非常有限。
编辑: 看来https://yonatankra.com/how-to-test-html5-canvas-with-jest/给出了另一种解释。
【讨论】:
以上是关于使用 Jest 的 canvas 元素的简单测试示例的主要内容,如果未能解决你的问题,请参考以下文章
错误:当我在 React 中尝试使用 Jest 进行测试时,无法找到带有文本的元素
使用 Jest 运行测试时,为啥 Trix 编辑器不会安装在 Vue 组件中?