使用 React 测试库获取 HTML 元素?

Posted

技术标签:

【中文标题】使用 React 测试库获取 HTML 元素?【英文标题】:Get by HTML element with React Testing Library? 【发布时间】:2019-06-11 13:40:34 【问题描述】:

我在 React 测试库中使用 getByTestId 函数:

const button = wrapper.getByTestId("button");
expect(heading.textContent).toBe("something");

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

const button = wrapper.getByHTML("button");
const heading = wrapper.getByHTML("h1");

【问题讨论】:

【参考方案1】:

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

你会这样做:

// Possible but not advisable
const  container  = render(<MyComponent />)
// `container` is just a DOM node
const button = container.querySelector('button')

既然你得到了一个 DOM 节点,你就可以使用所有普通的 DOM API,比如querySelector

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

以这种方式编写测试有点困难,但可以让您编写更健壮的测试。

在您的情况下,我认为底层 HTML 是一个实现细节。如果您更改 HTML 结构以使 h1 现在是 h2div 会发生什么?测试将中断。相反,如果您通过文本查看这些元素,则标签变得无关紧要。

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

【讨论】:

它确实使某些事情的测试变得更加困难。假设我有一个最初在页面加载时显示的加载器。我想确保它在出现数据表之前呈现。微调器没有任何与之关联的文本。 当 HTML 元素标签正是您希望覆盖以防止回归的东西时呢?也许出于可访问性目的,您希望确保它是一个 h2 并且测试应该中断。 然后测试它是h2,但这通常是例外而不是规则 我不明白为什么反应测试框架不支持getByDataAttribute("data-custom-value") 方法。这些不是实现细节,它们可以在任何元素上,可以在不破坏测试的情况下更改。为什么要限制测试特定的数据属性? 因为大多数时候这不是你想要测试的。您仍然可以使用 RTL 来做到这一点,但这并不是大多数应用程序的最佳方法【参考方案2】:

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

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

例如,level 对我测试默认 &lt;h1&gt; 元素是否被正确覆盖特别有用:

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

  expect(getByRole('heading',  level: 6 )).toBeInTheDocument()
)

【讨论】:

当然。在使用 React 测试库时,使用 *ByRole 查询(尽可能)是一种更惯用的解决方案。 +1 这是一个比公认的更好的答案——它测试重要的语义并被屏幕阅读器、爬虫等拾取,而另一个测试无关紧要的实现细节。 getByRole('button') 将匹配 &lt;button&gt;&lt;a role="button"&gt;,并且上面的示例将匹配 &lt;h6&gt;&lt;a role="heading" aria-level="6"&gt; - 这很好,因为关心这些角色的工具将(如果正确构建......)处理他们一样。

以上是关于使用 React 测试库获取 HTML 元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 测试库中获取 Material-UI 密码输入

如何使用 Jest 和/或 Enzyme 获取嵌套在 React 组件中的元素的属性?

使用反应测试库检查文本是不是出现在元素内

使用反应测试库测试离子组件

使用 rxjs 的 'fromEvent' 方法获取对 React 中元素的引用

前端库-React框架:「01] 创建一个简单的 JSX 元素