Search code examples
reactjstestingstyled-componentsreact-testing-library

What is the difference "getByText" and "getByTestId" ? In testing-library/react


What is the difference between getByText and getByTestId?

When I had tested a React component, there were some gaps between these two functions.

The test failed in getByText code, but it succeeded in getByTestId.

I have code that when an element was clicked, the color of the title changed to red.

Why this is the difference?

I omitted styled-components of Container and Content. This has props 'toggled' to change the color to red.

Here is the getByText code:

const { getByText } = render(<ListPresenter content={ListText} />);
const colorChangedText = getByText(/the party/);
fireEvent.click(colorChangedText);
screen.debug(); // The result of render I want !
expect(colorChangedText).toHaveStyle("color: red");    * failed

Here is the getByTestId code:

const { getByText } = render(<ListPresenter content={ListText} />);
fireEvent.click(getAllByTestId("list-element-toggle")[0]);
screen.debug(); // The result of render I want !
const colorChangedText = getAllByTestId("list-element-content")[0];
expect(colorChangedText).toHaveStyle("color: red");   * success

Here is the rendered component:

const Component = (props) => {
  return (
    <Container
        className="container"
        data-testid={"list-element-toggle"}
        toggled={state[data.id - 1]}
     >
        <Content className="content" data-testid={"list-element-content"} toggled={state[data.id - 1]}>
          {data.titleChild}.  // This text had been changed to red color when i was clicked.
        
        </div>
      </div>
  )
}

Solution

  • react-testing-library cheatsheet

    • ByText find by element text content
    • ByTestId find by data-testid attribute

    I've found that selecting by text can be a bit finicky and usually end up adding a testid attribute to query/target the exact element I want.

    My guess is the getByText may not be returning the correct element/wrapper.

    From your test code

    render(<ListPresenter content={ListText} />);
    

    It's not clear to me what the text in the test may be. It's not even clear to me if ListPresenter is the Component in the last snippet. For example, what is data.titleChild?

    See also Which query should I use?

    Queries Accessible to Everyone

    getByText: Not useful for forms, but this is the number 1 method a user finds most non-interactive elements (like divs and spans).

    Test IDs

    getByTestId: The user cannot see (or hear) these, so this is only recommended for cases where you can't match by role or text or it doesn't make sense (e.g. the text is dynamic).

    As a fallback there also Manual Queries.