You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试aria-expanded属性?Svelte组件测试点击后属性未更新

Svelte组件测试问题:aria-expanded属性测试不生效

我正在为一个简单的Svelte组件编写测试,测试代码如下:

it('opens and closes correctly', async () => {
render(Menubar, { menuData: menu_with_items });
const menuButton = screen.getByRole('button', { name: 'menu-item-1' });
expect(menuButton).toHaveAttribute('aria-expanded', 'false');
fireEvent.click(menuButton);
await waitFor(() => expect(menuButton).toHaveAttribute('aria-expanded', 'true'));
});

执行后输出错误信息:

expect(element).toHaveAttribute("aria-expanded", "true") //
element.getAttribute("aria-expanded") === "true" Expected the element
to have attribute: aria-expanded="true" Received:
aria-expanded="false"

我使用screen.debug()检查后发现,该元素的aria-expanded属性始终为false,但组件实际功能正常。请问我是否操作有误?有没有其他测试方法?


问题排查与解决方案

1. 换用更贴近真实交互的事件触发方式

fireEvent.click仅模拟DOM点击事件,可能无法覆盖Svelte组件内部的完整交互逻辑。改用@testing-library/user-event的点击方法,它更贴近真实用户操作流程:

import userEvent from '@testing-library/user-event';

it('opens and closes correctly', async () => {
  const user = userEvent.setup();
  render(Menubar, { menuData: menu_with_items });
  const menuButton = screen.getByRole('button', { name: 'menu-item-1' });
  
  expect(menuButton).toHaveAttribute('aria-expanded', 'false');
  await user.click(menuButton);
  expect(menuButton).toHaveAttribute('aria-expanded', 'true');
});

2. 通过菜单可见性间接验证展开状态

如果直接检测aria-expanded有问题,可以转而验证菜单内容的显示状态,间接确认组件已展开:

it('opens and closes correctly', async () => {
  render(Menubar, { menuData: menu_with_items });
  const menuButton = screen.getByRole('button', { name: 'menu-item-1' });
  
  expect(menuButton).toHaveAttribute('aria-expanded', 'false');
  fireEvent.click(menuButton);
  
  // 等待目标菜单项出现,验证菜单已展开
  await screen.findByRole('menuitem', { name: '对应菜单项名称' });
  expect(menuButton).toHaveAttribute('aria-expanded', 'true');
});

3. 检查组件内aria-expanded的绑定逻辑

确保组件中aria-expanded是绑定到Svelte响应式变量的,而非手动操作DOM属性。比如正确的绑定方式:

<button 
  role="button" 
  aria-expanded={isOpen}
  on:click={() => isOpen = !isOpen}
>
  menu-item-1
</button>

若组件是通过原生DOM API设置属性,测试可能无法同步捕获到状态变化。

4. 直接检查组件内部状态(调试用)

如果以上方法都无效,可以尝试获取组件实例,直接验证内部状态:

it('opens and closes correctly', async () => {
  const { component } = render(Menubar, { menuData: menu_with_items });
  const menuButton = screen.getByRole('button', { name: 'menu-item-1' });
  
  expect(menuButton).toHaveAttribute('aria-expanded', 'false');
  fireEvent.click(menuButton);
  
  // 假设组件内部有isOpen响应式变量
  await waitFor(() => expect(component.isOpen).toBe(true));
  expect(menuButton).toHaveAttribute('aria-expanded', 'true');
});

内容的提问来源于stack exchange,提问作者Raffaele Lungarella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:17:17