如何在react-testing-library中获取具有“name”属性的元素

Sat*_*chi 34 reactjs jestjs react-testing-library

我正在使用反应测试库和笑话来测试我的反应应用程序。

我想知道如何在react-testing-library中获取具有“name”属性的元素。

例如,在下面的页面中,是否可以通过“userName”获取此元素?

<input type="text" name="userName" />
Run Code Online (Sandbox Code Playgroud)

或者我应该设置data-testId到元素并使用getByTestId方法?

return (
  <div>
    <input type="text" name="userName" />
  </div>
)
Run Code Online (Sandbox Code Playgroud)

Hen*_*ody 39

您可以使用返回的container. 是container一个 DOM 节点并支持querySelector方法,该方法接受 CSS 选择器来查找元素。与这个更详细的答案中的方法相同。

例如:

const { container } = render(<MyComponent />);
const inputEl = container.querySelector(`input[name="userName"]`);
Run Code Online (Sandbox Code Playgroud)


jck*_*czk 27

在 DOM 中查找元素的一般推荐方法是采用类似于应用程序使用方式的方法。

在这个特定的示例中,name属性将不会被识别,如 @ggorlen 所指出的。

作为文本输入的后备,您可以依赖getByLabelText(假设您已添加带有 的标签htmlFor),或者您可以添加aria-label到文本输入:

<input type="text" aria-label="userName" />
Run Code Online (Sandbox Code Playgroud)

然后使用:

screen.getByRole("textbox", {name: /userName/i});
Run Code Online (Sandbox Code Playgroud)

的“问题”data-testid是你必须专门为你的测试添加它,而不是依赖更自然的findByRole, findByPlaceholderText, findByLabelText

getByTestId应该是你最后的手段。

作为后续,我建议使用 Test Playground 浏览器扩展,它会生成元素的 RTL 查询,其方式与在浏览器开发工具中查找元素类似。

此外,当遇到按名称(或其他属性)搜索时,请尝试研究给定元素/组件的可访问性特征,以准确地确定如何搜索它。

  • 这里可能对“名称”有些混淆。这是 aria 可访问的名称,而不是 `name="userName"` 属性。请参阅[react-testing-library中的名称选项是什么?](/sf/ask/4843923451/#69227320) 。 (2认同)

ggo*_*len 5

在某些情况下,您可以按角色(或者不太理想的是,按测试 id)选择元素,然后断言相关属性存在,而不是求助于本机 DOM ,以代替一体化调用getBy

expect(screen.getByRole("textbox")).toHaveAttribute("name", "userName");
Run Code Online (Sandbox Code Playgroud)

很遗憾,

screen.getByRole("textbox", {name: "userName"});
Run Code Online (Sandbox Code Playgroud)

并没有像它应该的那样工作。请参阅react-testing-library 中的 name 选项是什么?以获得解释。

证明:

import React from "react"; // 18.2.0
import {render, screen} from "@testing-library/react"; // 13.4.0
import "@testing-library/jest-dom/extend-expect"; // ^5.16.5

describe("getByRole experiments", () => {
  beforeEach(() => render(<input type="text" name="userName" />));

  it("should work with a plain getByRole", () => {
    expect(screen.getByRole("textbox"))
      .toHaveAttribute("name", "userName"); // OK
  });

  it("will fail specifying {name: /userName/i}", () => {
    screen.getByRole("textbox", {name: /userName/i}); // Fails
  });

  it('will also fail specifying {name: "userName"}', () => {
    screen.getByRole("textbox", {name: "userName"}); // Fails
  });
});
Run Code Online (Sandbox Code Playgroud)

部分输出(name: "userName"断言失败基本相同):

TestingLibraryElementError: Unable to find an accessible element with the role "textbox" and name `/userName/i`

Here are the accessible roles:

  textbox:

  Name "":
  <input
    name="userName"
  />

  --------------------------------------------------

Ignored nodes: comments, <script />, <style />
<body>
  <div>
    <input
      name="userName"
    />
  </div>
</body>
Run Code Online (Sandbox Code Playgroud)

另请参阅React 测试库:如何在自定义角色上 getByRole