40

I'm using the getByTestId function in React Testing Library:

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

Is it possible / advisable to search for HTML elements instead? So something like this:

const button = wrapper.getByHTML("button");
const heading = wrapper.getByHTML("h1");
Evanss
  • 17,152
  • 66
  • 217
  • 397

1 Answers1

79

I'm not sure what wrapper is in this case. But to answer your two questions: yes it's possible to get by HTML element and no, it's not advisable.

This is how you would do it:

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

Since you get back a DOM node you can use all the normal DOM APIs such as querySelector.

Now, why is this not advisable. A big selling point of react-testing-library is that you test your components as a user does. This means not relying on implementation details. For instance, you don't have direct access to a component's state.

Writing tests this way is a bit harder but allows you to write more robust tests.

In your case, I would argue that the underlying HTML is an implementation detail. What happens if you change your HTML structure so that the h1 is now an h2 or a div? The test will break. If instead, you look at these elements by text the tag becomes irrelevant.

In some cases, the normal query helpers are not enough. For those events you can use a data-testid and use getByTestId.

Giorgio Polvara - Gpx
  • 12,268
  • 5
  • 53
  • 55
  • 18
    It does making testing for some things harder. Say I have a loader that is displayed initially on page load. I want to make sure it renders before, say, a table of data appears. The spinner does not have any text associated with it. – Gilbert Nwaiwu Nov 11 '19 at 16:48
  • 5
    And what about when the HTML element tag is exactly the thing you wish to cover against regressions? perhaps for accessibility purposes you want to *ensure* that its an h2 and the test *should* break. – Code Novitiate Apr 06 '20 at 02:18
  • Then test that it's an `h2`, but that's usually the exception rather than the rule – Giorgio Polvara - Gpx Apr 20 '20 at 16:20
  • 4
    What I dont understand is why react test framework does not support a `getByDataAttribute("data-custom-value")` method. These are not implementation details, they can be on any elements, which can change without breaking tests. Why limit things to a test specific data attribute? – Jeremy Apr 22 '20 at 13:31
  • Because most of the time that's not what you want to test. You can still do it with RTL but it's not the best approach for most applications – Giorgio Polvara - Gpx Apr 22 '20 at 17:06
  • You could use the getAllByRole("button") or getByRole("button"), se https://testing-library.com/docs/queries/byrole/ – fedda Mar 05 '21 at 13:32