# React Testing Helper

> Helps write and debug React component tests using React Testing Library. Use when writing unit tests for React components, debugging test failures, or setting up testing infrastructure.

- Skill: `alexngai/react-testing-helper` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add alexngai/react-testing-helper`
- Raw SKILL.md: https://api.skillmd.com/api/skills/alexngai/react-testing-helper/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: alexngai (https://skillmd.com/u/alexngai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/alexngai/react-testing-helper

---


# React Testing Helper

A comprehensive skill for writing effective React component tests.

## When to Use

- Writing unit tests for React components
- Debugging failing component tests
- Setting up React Testing Library
- Testing user interactions and async behavior

## Quick Reference

```javascript
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

// Basic render
render(<MyComponent prop="value" />);

// Query elements
screen.getByRole('button', { name: /submit/i });
screen.getByText(/welcome/i);
screen.getByTestId('my-element');

// User interactions
await userEvent.click(button);
await userEvent.type(input, 'hello');

// Async assertions
await waitFor(() => {
  expect(screen.getByText('loaded')).toBeInTheDocument();
});
```

## Best Practices

1. **Query by accessibility**: Prefer `getByRole`, `getByLabelText` over `getByTestId`
2. **Test behavior, not implementation**: Focus on what users see and do
3. **Use userEvent over fireEvent**: More realistic user interactions
4. **Avoid testing implementation details**: Don't test state or internal methods

## Common Patterns

### Testing Forms

```javascript
test('submits form with user data', async () => {
  const onSubmit = jest.fn();
  render(<LoginForm onSubmit={onSubmit} />);

  await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
  await userEvent.type(screen.getByLabelText(/password/i), 'password123');
  await userEvent.click(screen.getByRole('button', { name: /submit/i }));

  expect(onSubmit).toHaveBeenCalledWith({
    email: 'test@example.com',
    password: 'password123'
  });
});
```

### Testing Async Components

```javascript
test('loads and displays data', async () => {
  render(<DataLoader />);

  expect(screen.getByText(/loading/i)).toBeInTheDocument();

  await waitFor(() => {
    expect(screen.getByText(/data loaded/i)).toBeInTheDocument();
  });
});
```

## Troubleshooting

- **Element not found**: Use `screen.debug()` to see current DOM
- **Act warnings**: Wrap state updates in `act()` or use `waitFor`
- **Stale queries**: Re-query elements after state changes

