React
This guide covers how to test React applications and components with Rstest. Rstest supports testing React in multiple scenarios:
- Node (with happy-dom or jsdom): Fast, lightweight tests running in Node.js with a simulated DOM
- SSR (Server-Side Rendering): Test server render functions in pure Node.js environment
- Browser Mode: Real browser testing with Playwright for accurate DOM behavior
Node testing
Node-based testing uses DOM simulators like happy-dom or jsdom to provide a DOM environment in Node.js. This approach is faster and suitable for most component testing scenarios.
Quick start
1. Install dependencies
npm add @rstest/core @rsbuild/plugin-react @testing-library/react @testing-library/jest-dom happy-dom -D
yarn add @rstest/core @rsbuild/plugin-react @testing-library/react @testing-library/jest-dom happy-dom -D
pnpm add @rstest/core @rsbuild/plugin-react @testing-library/react @testing-library/jest-dom happy-dom -D
bun add @rstest/core @rsbuild/plugin-react @testing-library/react @testing-library/jest-dom happy-dom -D
deno add npm:@rstest/core npm:@rsbuild/plugin-react npm:@testing-library/react npm:@testing-library/jest-dom npm:happy-dom -D
Create rstest.config.ts:
rstest.config.ts
import { pluginReact } from '@rsbuild/plugin-react';
import { defineConfig } from '@rstest/core';
export default defineConfig({
plugins: [pluginReact()],
testEnvironment: 'happy-dom',
});
3. Setup test matchers (Optional)
For enhanced DOM assertions with jest-dom matchers, create a setup file:
rstest.setup.ts
import { afterEach, expect } from '@rstest/core';
import { cleanup } from '@testing-library/react';
import * as jestDomMatchers from '@testing-library/jest-dom/matchers';
expect.extend(jestDomMatchers);
// Cleanup after each test to prevent test pollution
afterEach(() => {
cleanup();
});
Then add it to your config:
rstest.config.ts
import { pluginReact } from '@rsbuild/plugin-react';
import { defineConfig } from '@rstest/core';
export default defineConfig({
plugins: [pluginReact()],
testEnvironment: 'happy-dom',
setupFiles: ['./rstest.setup.ts'],
});
4. Write your first test
src/App.test.tsx
import { expect, test } from '@rstest/core';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders greeting', () => {
render(<App />);
expect(screen.getByText('Hello World')).toBeInTheDocument();
});
Reusing Rsbuild configuration
If your project already uses Rsbuild, you can reuse your existing configuration with @rstest/adapter-rsbuild:
npm add @rstest/adapter-rsbuild -D
yarn add @rstest/adapter-rsbuild -D
pnpm add @rstest/adapter-rsbuild -D
bun add @rstest/adapter-rsbuild -D
deno add npm:@rstest/adapter-rsbuild -D
rstest.config.ts
import { withRsbuildConfig } from '@rstest/adapter-rsbuild';
import { defineConfig } from '@rstest/core';
export default defineConfig({
extends: withRsbuildConfig(),
testEnvironment: 'happy-dom',
setupFiles: ['./rstest.setup.ts'],
});
This will automatically inherit your Rsbuild plugins, aliases, and other build configuration.
Testing components
Use @testing-library/react to render and query components:
src/Counter.test.tsx
import { expect, test } from '@rstest/core';
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('increments counter on click', () => {
render(<Counter />);
const button = screen.getByRole('button');
expect(screen.getByText('Count: 0')).toBeInTheDocument();
fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
Mocking modules
Use rs.mock() to mock dependencies:
src/UserProfile.test.tsx
import { expect, rs, test } from '@rstest/core';
import { render, screen } from '@testing-library/react';
import UserProfile from './UserProfile';
rs.mock('./api', () => ({
fetchUser: () => Promise.resolve({ name: 'John Doe' }),
}));
test('renders user name', async () => {
render(<UserProfile userId="1" />);
expect(await screen.findByText('John Doe')).toBeInTheDocument();
});
SSR testing
Rstest supports testing React Server-Side Rendering (SSR) scenarios. You can test your server render functions using react-dom/server.
Example
First, create a server render function:
src/index.server.tsx
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';
export function render() {
return ReactDOMServer.renderToString(
<React.StrictMode>
<App />
</React.StrictMode>,
);
}
Then test it:
test/ssr.test.ts
import { expect, test } from '@rstest/core';
import { render } from '../src/index.server';
test('renders correctly on server', () => {
const html = render();
expect(html).toContain('Hello World');
expect(html).toMatchSnapshot();
});
SSR tests run in Node.js environment without a DOM simulator, which is the default testEnvironment: 'node' setting.
Browser mode testing
For scenarios requiring real browser behavior (e.g., CSS rendering, Web APIs, visual testing), use Rstest's Browser Mode with Playwright.
See the Browser Testing - Framework Guides for detailed setup and usage instructions.
Recommendations:
- Use Node testing for unit tests, logic-heavy components, and fast feedback
- Use Browser Mode for integration tests, visual behavior, and when you need real browser APIs
Example projects
- react - React testing with happy-dom (includes component, hook, and SSR tests)
- react-rsbuild - React testing with Rsbuild adapter
- browser-react - React testing in Browser Mode