如何使用 React 测试库找到并单击没有文本的按钮?

How can I find and click a button that has no text using React Testing Library?

许多 React Testing Library 示例展示了如何使用 getByText 查询查找和单击按钮,如:

fireEvent.click(getByText("Create"))

userEvent.click(getByText("Create"))

但是,没有文本且只有 SVG 图标的按钮很常见,例如 Material UI 的 icon buttons or floating action buttons. Is there a recommended way to query for and click buttons like these? For context, I'm using the higher-level events provided by the companion user-event 库。

有几种方法可以查询一个元素,在没有看到你的元素层次结构的情况下,很难说。但是,有几种查询元素的方法,使用 getByText() 的替代方法可能是 getByRole('button')。如果要向元素添加 data-testid,可以使用 getByTestId()。这里有一些可用的查询:https://testing-library.com/docs/dom-testing-library/api-queries

有很多不同的方法可以做到这一点,包括每个人最喜欢的后备方法,data-tested。但是,如果您使用 Material UI,您可能正在寻找最 "MUI" 的方式来执行此操作。两个想法:

  • MUI documentation 显示其所有按钮都包含在 label 元素和 htmlFor 属性 中。您可以这样做,然后使用 getByLabelText()
  • 您的图标按钮可能有(并且应该!)工具提示,并且工具提示文本可能来自 title 属性。然后你可以用 getByTitle().
  • 得到按钮

对于图标按钮,添加一个 aria-label 属性,如下所示:

<button aria-label='edit'>
  <edit-icon />
</button>

然后在你的测试中,调用时传递可访问的名称getByRole()

screen.getByRole('button', {
  name: /edit/i
})

来自docs

The accessible name is for simple cases equal to e.g. the label of a form element, or the text content of a button, or the value of the aria-label attribute.

查找元素的最佳方法是模拟最面向用户的方法。因此,用户可能需要角色按钮,然后在您的案例中搜索图标。这就是语义 HTML 在组件内部的元素结构中发挥作用的地方。

MUI 按钮还为其他组件中使用的某些图标按钮实现了 name 属性,例如Select 我强烈建议使用此属性进行测试。

请记住,您的测试应该不知道实现,因此识别应该依赖于 namerolelabel 和其他“自然”属性。但如果那是不可能的,那么使用 data-testid 应该是你最后的选择。

一个非常好的总体方法(不仅适用于图标按钮)是在 getByRole 查询中指定一个名称 属性 以及角色:

const listOpenButton = screen.getByRole("button", { name: /open/i });

也是一种数据测试方法:

const listOpenButton = screen.getByTestId("myButtonId");

对我来说,以上答案均无效,对我有用的是:

screen.getByRole('button', { name: /<icon-file-name>/i });

在我的例子中,按钮只有 svg 文件。