SmartCodingTips

๐Ÿ–ฑ๏ธ User Interaction Testing in React

Testing how users interact with your components โ€” like clicking buttons, typing in forms, or submitting data โ€” is essential to ensure your app behaves correctly in real-world usage.


๐ŸŽฏ 1. Why Test User Interactions?

  • Verify UI updates correctly on user actions
  • Ensure form validation and submission logic works
  • Prevent regressions in core UI functionality

โš™๏ธ 2. fireEvent vs userEvent

  • fireEvent: Simulates DOM events (basic, low-level)
  • userEvent: Simulates real user behavior (recommended)

๐Ÿงช 3. Example: Button Click


// Counter.js
export default function Counter() {
  const [count, setCount] = React.useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

// Counter.test.js
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';

test('increments count on click', async () => {
  render(<Counter />);
  const button = screen.getByText('Increment');
  await userEvent.click(button);
  expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

โŒจ๏ธ 4. Example: Typing in Input


// Greeting.js
export default function Greeting() {
  const [name, setName] = React.useState('');
  return (
    <div>
      <input
        placeholder="Enter name"
        onChange={(e) => setName(e.target.value)}
      />
      <p>Hello {name}</p>
    </div>
  );
}

// Greeting.test.js
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Greeting from './Greeting';

test('updates name on typing', async () => {
  render(<Greeting />);
  const input = screen.getByPlaceholderText('Enter name');
  await userEvent.type(input, 'React');
  expect(screen.getByText('Hello React')).toBeInTheDocument();
});

โœ… 5. Best Practices

  • Use userEvent for more realistic simulations
  • Query elements the way users would (e.g., by role, label)
  • Wrap async interactions in await
  • Check visible text and screen updates, not internal state

๐Ÿ“‹ Summary

  • User interaction tests help you verify dynamic behaviors
  • userEvent is better than fireEvent for simulating real usage
  • Test inputs, clicks, form submission, and validation thoroughly