Why You Should Not Use Classes in React Testing Library

Ferenc Almasi β€’ 2022 September 16 β€’ πŸ“– 3 min read
  • twitter
  • facebook

You might be tempted to query elements by their class name in React Testing Library to test their presence. However, this approach is strongly discouraged.

import React from 'react'
import { render } from '@testing-library/react'
import { Component } from '@components'

// πŸ”΄ Don't
describe('Selectors', () => {
    it('should query the element by its className', () => {
        const { container } = render(<Component />)
        const domElement = container.getElementsByClassName('container')[0]

        expect(domElement).toBeInTheDocument()
    })
})
Don't use class name for querying elements in React Testing Library
Copied to clipboard!

Instead of using class names for querying elements, use selectors provided by React Testing Library, such as getByTestId, getByText, or getByRole. React Testing Library does not have a built-in way to select elements by class names for a reason.

// βœ… Do
describe('Selectors', () => {
    it('should query the element by its className', () => {
        render(<Component />)

        expect(screen.getByTestId('element')).toBeInTheDocument() // Using data-testid attribute
        expect(screen.getByText('content')).toBeInTheDocument() // Using text content
        expect(screen.getByRole('button')).toBeInTheDocument() // Using the node type

        // Use getAllBy for multiple elements
        expect(screen.getAllByTestId('element')).toHaveLength(3)
        expect(screen.getAllByText('content')).toHaveLength(3)
        expect(screen.getAllByRole('button')).toHaveLength(3) 
    })
})
Copied to clipboard!

For using getByTestId, you first want to define a data-testid property on your element.

Class names are an implementation detail that can make your unit test suite less resilient. If the class name changes but the functionality remain the same, your tests will need to be updated, otherwise, they will fail.


If you are using Tailwind, your queries also won't be descriptive in your test cases, meaning it's hard to tell what is the purpose of the queried element.

describe('Selectors', () => {
    it('should query the element by its className', () => {
        const { container } = render(<Component />)
        // ❓ What is the purpose of this element? What are we querying exactly?
        const domElement = container.getElementsByClassName('md:max-w-screen-xl')[0]

        expect(domElement).toBeInTheDocument()
    })
})
Copied to clipboard!

If you specifically need to test the existence of class names on an element, you can do so by using a toHaveClass assertion. However, you should avoid querying elements by their class names or ids.

describe('Selectors', () => {
    it('should query the element by its className', () => {
        render(<Component />)

        expect(screen.getByTestId('element')).toHaveClass('open')
        expect(screen.getByTestId('element')).not.toHaveClass('closed')
    })
})
Testing for the presence or absence of class names
Copied to clipboard!

If you are interested in more unit test best practices to get the best out of your test suite, make sure you have a look at the article below.

11 Jest Best Practices to Get the Most Out of Your Tests
  • twitter
  • facebook
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Unlimited access to hundred of tutorials
  • check Access to exclusive interactive lessons
  • check Remove ads to learn without distractions
Become a Pro

Recommended