在 react-testing-library 中按 id 查找元素
Posted
技术标签:
【中文标题】在 react-testing-library 中按 id 查找元素【英文标题】:Find element by id in react-testing-library 【发布时间】:2019-03-30 21:52:17 【问题描述】:我正在使用react-testing-libarary 来测试我的 React 应用程序。出于某种原因,我需要能够通过id
而不是data-testid
找到元素。文档中没有办法实现这一点。
有没有办法做到这一点?
我的渲染输出为:
const dom = render(<App />);
我正在寻找符合以下条件的东西:
const input = dom.getElemenById('firstinput');
//or
const input = dom.getById('firstinput');
【问题讨论】:
这对我有用:document.getElementById('firstinput')
【参考方案1】:
我觉得没有一个答案真正给出了完整的解决方案,所以这里是:
const result = render(<SomeComponent />);
const someElement = result.container.querySelector('#some-id');
【讨论】:
对我不起作用。但是当我登录result.debug()
时,我可以清楚地看到具有该 ID 的元素。 :(【参考方案2】:
我找到了一种方法。
import App from './App';
import render, queryByAttribute from 'react-testing-library';
const getById = queryByAttribute.bind(null, 'id');
const dom = render(<App />);
const table = getById(dom.container, 'directory-table');
我希望这会有所帮助。
【讨论】:
为什么他们默认没有这个??我不敢相信。 简单地使用document.getElementById
会容易得多。但是元素的 ID 是一个实现细节,我建议不要使用它。
@Victor 相信它。用户不会按 ID 填写元素,因此测试也不应该(至少根据 react-testing-library 的理念)。他们通过标签填写它们,因此您应该以与用户查找元素相同的方式在测试中找到您的元素:通过标签或占位符文本或其他方式。
@Imat - 恢复莫妮卡,好吧,我讨论了#id 解决方案可能是理想方案的一些场景。一切都取决于场景。一个简单的例子:当使用第三方库(如 Kendo)时,通过您提供的#id 构建元素,您可以创建依赖于 id 的测试来访问元素。使用#id 将保持与第三方库的新版本的兼容性,并且它也不会用 data-test-id 污染我们的代码。我在这里更深入地解释了这一点:github.com/testing-library/react-testing-library/issues/…
继续滚动直到@Liran H 回答。【参考方案3】:
看起来你的 DOM 节点本身是 container。因此,您应该可以使用它调用.querySelector('#firstinput')
。
【讨论】:
是的,这行得通,但这里唯一的问题是现在我无法在这个返回的节点上使用react-testing-library
助手。
如果你不需要帮助器,不使用它们没有错
“我无法在这个返回的节点上使用 react-testing-library 助手。”这是不正确的。你说的是什么帮手?所有助手都处理常规的 DOM 节点,因此您如何找到它并没有什么不同。但无论哪种方式,通过 ID 查找元素都不包含在库中,因为这是一个实现细节。使用内置查询之一。
Liran H 的回答比较好。有些人可能不明白你的意思。举一个像他这样的完整例子更好。
这是实现这一目标的最快、最简单的方法。拥抱【参考方案4】:
您可以在配置中设置testIdAttribute
。
configure( testIdAttribute: 'id' )
https://testing-library.com/docs/dom-testing-library/api-configuration
设置有利有弊。这样做的好处是您可以设置一个 id 用于多种用途。 (测试 id、营销分析、标签管理器等)您不必同时添加 id 和 test-id。有利于代码的简洁。
但请注意,您可能会不小心在同一页面上的两个不同组件中设置了相同的 id。记得为列表项的组件 ID 添加索引或标识。
【讨论】:
testIdAttribute
:getByTestId 和相关查询使用的属性。默认为data-testid
。
这是个坏主意,因为 id 对整个页面上的单个元素来说是唯一的,而测试 id 可以用于多个元素(例如列表项)。
是的,你可能是对的。但是,如果我们需要将 id 用于多种用途,则设置有一些好处。 (例如标签管理器)【参考方案5】:
有两种方法可以做到这一点
-
只需使用
container.getElementById('id')
。最后,所有助手所做的都是在后台进行类似这样的查询
如果您想要自定义查询,您可以编写自定义渲染。查看文档以获取更多信息https://github.com/kentcdodds/react-testing-library#getbytestidtext-textmatch-htmlelement
最后一点,如果您可以避免通过 id 查找元素,那就更好了。
【讨论】:
我认为您无权访问容器上的 getElementById。 这是正确答案。 (我是测试库的作者)。 尝试登录container
我猜这不是你要找的
@kentcdodds 我的意思是,如果那样工作(从 1 开始)会很好,但我得到的只是TS2339: Property 'getElementById' does not exist on type 'HTMLElement'.
getElementById
甚至没有出现在 RTL 文档中'-' 对我来说,正确的方法是使用这个工具:chrome.google.com/webstore/detail/testing-playground/… 我再也没有花时间添加/查找 ID。【参考方案6】:
我的建议:停止添加和搜索 id,这总是需要花费大量时间和精力,因为您必须添加 id(有时是 test-id),然后找出查询元素的最佳方法。但即使你真的需要一个 id,这个工具也会通过显示在你的屏幕上查询任何 DOM 元素的最佳方式为你节省大量时间:Testing Playground
【讨论】:
以上是关于在 react-testing-library 中按 id 查找元素的主要内容,如果未能解决你的问题,请参考以下文章
如何在 react-testing-library 中访问 prop 值
使用 react-testing-library 在 useEffect 中测试 api 调用
Codesandbox.io 中的 React-Testing-Library 问题
酶、ReactTestUtils 和 react-testing-library 之间的区别
如何在使用 react-testing-library 和 jest 完成的单元测试中启用 react-i18n 翻译文件?