自定义元素需测试javascript行为、dom响应和生命周期钩子;注册须验证customelements.get()返回构造函数且实例继承正确;connectedcallback需插入dom才触发,attributechangedcallback不响应初始属性;shadow dom断言须用shadowroot.queryselector而非innerhtml;事件监听与触发需在dom中进行并等待异步更新。

自定义元素本身不能直接单元测试,必须测它的 JavaScript 行为、DOM 响应和生命周期钩子是否按预期工作。 直接对 <my-button></my-button> 写断言没意义——浏览器不执行逻辑,它只渲染标签;真正要验证的是:注册是否成功、属性是否同步、connectedCallback 是否触发、事件是否派发、Shadow DOM 是否正确注入。
customElements.define() 注册失败的常见表现与验证方式
注册失败时,页面里写 <my-button></my-button> 不会报错,但元素不会升级(即仍是普通 HTMLUnknownElement),后续所有行为测试都会失效。
- 先确认注册语句执行无异常:
customElements.define('my-button', MyButton)必须在<script></script>中同步执行,且不能重复注册同名元素(否则抛NotSupportedError) - 验证是否注册成功:
customElements.get('my-button')应返回构造函数,返回undefined说明未注册或名字非法(比如缺连字符、用了大写字母) - 创建实例后检查原型链:
document.createElement('my-button') instanceof MyButton必须为true,否则生命周期钩子根本不会调用
测试 connectedCallback 和 attributeChangedCallback 的时机陷阱
connectedCallback 只在元素被插入文档时触发,attributeChangedCallback 对初始 HTML 属性值不响应——这是最容易漏测的点。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 测试
connectedCallback时,必须把元素 append 到document.body或一个真实父节点,仅document.createElement()不会触发它 - 测试属性变更:先设置
el.setAttribute('label', 'Save'),再改值el.setAttribute('label', 'Submit'),才能触发attributeChangedCallback - 初始属性值(如
<my-input value="abc"></my-input>)不会进attributeChangedCallback,需在connectedCallback里手动调用this.getAttribute('value')同步
Shadow DOM 渲染与样式隔离的断言要点
Shadow DOM 是封装核心,但测试时容易误判:外部 CSS 不生效是正常现象,关键看内部结构是否按预期生成。
- 不要用
el.innerHTML断言 Shadow 内容——它永远为空;必须访问el.shadowRoot.innerHTML或用el.shadowRoot.querySelector() - 若组件用了
mode: 'closed',shadowRoot为null,测试将失败;一律用mode: 'open'便于断言 - 样式注入必须显式进行:在
connectedCallback中动态创建<style></style>标签并 append 到shadowRoot,否则 Shadow 内部无样式可测 - 避免断言完整 HTML 字符串(如
expect(el.shadowRoot.innerHTML).toBe(...)),优先用screen.getByRole()或el.shadowRoot.querySelector('[aria-label]')验证语义结构
事件监听与异步行为的模拟边界
自定义元素常派发自定义事件,但测试中容易忽略事件冒泡路径、取消默认行为、以及异步更新后的 DOM 状态。
- 监听事件必须在元素插入 DOM 后绑定:
el.addEventListener('submit', handler),不能在createElement()后立即监听 - 触发事件用
fireEvent.click(el.shadowRoot.querySelector('button'))(@testing-library/dom),而不是el.click()—— 后者不触发 Shadow 内部按钮的原生点击 - 若事件处理中修改了属性并引发重新渲染(如
this.setAttribute('loading', 'true')),需用await waitFor(() => expect(...).toBe(true))等待 DOM 更新完成 - 禁用态、加载态等视觉反馈,不能只断言属性存在,要结合
getComputedStyle()或实际 class/aria 属性验证用户可见状态
最常被跳过的其实是初始属性同步和 Shadow DOM 的可访问性验证——写完 attributeChangedCallback 就以为属性能响应,但首次渲染的值往往被忽略;而没检查 shadowRoot 是否存在,就直接 querySelector,结果永远找不到元素。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










