Suleman Ahmed - BlogA Guide to Effective Unit Testing with Vitest and React Testing Library

Testing is the key to maintaining large applications with confidence. Vitest has replaced Jest as the modern, fast test runner, integrating perfectly with Vite and React.

Testing Best Practices

Avoid testing implementation details like state variables. Instead, test behavior from the perspective of the user (e.g., click a button, verify text is shown on the screen).

An RTL and Vitest Example

Let's write a simple button component and a test suite to verify its behavior:

components/CounterButton.tsxtypescript
import { useState } from 'react';

export default function CounterButton() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)} className="border p-2">
      Clicked {count} times
    </button>
  );
}

Now here is the test suite using Vitest and React Testing Library:

components/__tests__/CounterButton.test.tsxtypescript
import { describe, test, expect } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import CounterButton from '../CounterButton';

describe('CounterButton', () => {
  test('increments counter on click', () => {
    render(<CounterButton />);
    
    const button = screen.getByRole('button');
    expect(button).toHaveTextContent('Clicked 0 times');
    
    // Simulate user click
    fireEvent.click(button);
    expect(button).toHaveTextContent('Clicked 1 times');
  });
});

Why Vitest?

Vitest shares configuration with Vite, meaning zero extra configuration files for test-runners, native ES module support, and lightning-fast file watch speeds.

Adding automated unit tests ensures your application logic remains solid as you build features and refactor code.

© 2026 Suleman Ahmed. All rights reserved.

Built with Next.js, Tailwind CSS & Sanity.