通过React Testing Library获得HTML元素?

Eva*_*nss 15 react-testing-library

我正在使用getByTestIdReact Testing库中的函数:

const button = wrapper.getByTestId("button");
expect(heading.textContent).toBe("something");
Run Code Online (Sandbox Code Playgroud)

是否可以/建议搜索HTML元素?所以像这样:

const button = wrapper.getByHTML("button");
const heading = wrapper.getByHTML("h1");
Run Code Online (Sandbox Code Playgroud)

小智 37

根据您要查询的元素类型,您可能还会发现该byRoleAPI 很有用:

https://testing-library.com/docs/queries/byrole/

例如,level对于我测试默认<h1>elem 是否被正确覆盖特别有用:

it('correctly renders override header level', () => {
  const { getByRole } = render(<Heading overrideHeadingLevel="h6" />)

  expect(getByRole('heading', { level: 6 })).toBeInTheDocument()
})
Run Code Online (Sandbox Code Playgroud)


Gio*_*Gpx 28

我不确定wrapper在这种情况下是什么。但是要回答您的两个问题:是的,可以通过HTML元素获得,否,这是不可取的。

这是您的操作方式:

// Possible but not advisable
const { container } = render(<MyComponent />)
// `container` is just a DOM node
const button = container.querySelector('button')
Run Code Online (Sandbox Code Playgroud)

由于您返回了DOM节点,因此可以使用所有常规DOM API,例如querySelector

现在,为什么不建议这样做。react-testing-library的一大卖点是您像用户一样测试组件。这意味着不依赖实施细节。例如,您没有直接访问组件状态的权限。

用这种方式编写测试会比较困难,但是可以编写更强大的测试。

就您而言,我认为底层HTML是实现细节。如果您更改HTML结构,以使h1现在为an h2或a,会发生div什么?测试将失败。相反,如果您通过文本查看这些元素,则标记将变得无关紧要。

在某些情况下,普通的查询助手是不够的。对于这些事件,您可以使用data-testid和使用getByTestId

  • 它确实使某些事情的测试变得更加困难。假设我有一个加载器,最初在页面加载时显示。我想确保它在数据表出现之前呈现。微调器没有任何与之关联的文本。 (20认同)
  • 当 HTML 元素标签正是您希望防止回归的内容时该怎么办?也许出于可访问性的目的,您希望“确保”它是 h2 并且测试“应该”中断。 (5认同)
  • 我不明白的是为什么 React 测试框架不支持 `getByDataAttribute("data-custom-value")` 方法。这些不是实现细节,它们可以位于任何元素上,可以在不破坏测试的情况下进行更改。为什么要限制测试特定数据属性? (4认同)

sam*_*war 7

另一种可能的解决方案

考虑渲染您的组件。

render(<ReactComponent />);

const button = screen.getByText((content, element) => element.tagName.toLowerCase() === 'button');
Run Code Online (Sandbox Code Playgroud)

如果您有多个按钮,请使用getAllByText并引用您需要选择的目标元素。