"I didn't fail the test, I just found 100 ways to do it wrong."
"I didn't fail the test, I just found 100 ways to do it wrong."
在编写测试时有时候我们需要生成大量不同 DOM 元素来进行测试。本文将聊聊几种生成 DOM 元素的方式以及它们的优劣势。
首先我们以一个基本的 HTML 作为例子,这是我们的目标:
<!DOCTYPE html>
<html>
<body>
<div id="root">
<h1 class="title">Test Title</h1>
<p>Test Paragraph <a href="https://blog.crimx.com">Test Link</a> End</p>
</div>
</body>
</html>
创建 DOM 元素最直接的方式是通过 DOM APIs。
const root = document.createElement('div')
root.id = 'root'
const title = document.createElement('h1')
title.textContent = 'Test Title'
root.appendChild(title)
const p = document.createElement('p')
root.appendChild(p)
p.appendChild(document.createTextNode('Test Paragraph '))
const a = document.createElement('a')
a.href = 'https://blog.crimx.com'
a.textContent = 'Test Link'
p.appendChild(a)
p.appendChild(document.createTextNode(' End'))
document.body.appendChild(root)
另一个最常见的方式是编写 HTML 字符串,通过 innerHTML
解析生成 DOM 元素。
const root = document.createElement('div')
root.id = 'root'
root.innerHTML = `
<h1 class="title">Test Title</h1>
<p>Test Paragraph <a href="https://blog.crimx.com">Test Link</a> End</p>
`
document.body.appendChild(root)
这个问题其实正是 React 团队创造 JSX 语法糖的原因。利用 JSX 我们可以在 JS 文件中编写 Markup,然后转换成相应的 JavaScript 代码。
默认情况下,JSX 生成的渲染函数是 React.createElement(component, props, ...children)
。然而 JSX 只是语法糖,各种 JSX(TSX) 编译器都提供了选项来自定义生成的函数名。我们完全可以换成直接生成 DOM 的库。
如 @babel/plugin-transform-react-jsx 提供了 pragma
等选项;TypeScript 可以在 tsconfig.json 中配置 jsxFactory
。
Babel 例子中配合了 deku 生成 DOM,这个库有点老,写测试也不需要虚拟 DOM 来操作,建议使用更轻量的 tsx-dom(也支持 JSX)。
document.body.appendChild(
<div id='root'>
<h1 class='title'>Test Title</h1>
<p>Test Paragraph <a href='https://blog.crimx.com'>Test Link</a> End</p>
</div>
)
如果测试需要大量编写 DOM 元素,使用 JSX 的方式无疑是最方便可靠的;如果只是少量几个测试,可以用 innerHTML
的方式凑合用;一遍不建议使用 DOM APIs ,因为测试首要考虑的应该是直观。
评论没有加载,检查你的局域网
Cannot load comments. Check you network.