If you are using the Rstack (Rsbuild / Rslib / Rspack, etc.) toolchain, migrating to Rstest will bring you a consistent development experience.
First, you need to install the Rstest dependency.
npm add @rstest/core -DNext, update the test script in your package.json to use rstest instead of vitest. For example:
"scripts": {
- "test": "vitest run"
+ "test": "rstest"
}Update your Vitest configuration file (e.g., vite.config.ts or vitest.config.ts) to an rstest.config.ts file:
import { defineConfig } from '@rstest/core';
export default defineConfig({
include: ['**/*.{test,spec}.?(c|m)[jt]s?(x)'],
});Rstest test configuration is basically the same as Vitest, but note that you don't need to put test configuration under the test field.
Additionally, there are some configuration changes to be aware of, such as test.environment needs to be changed to testEnvironment.
You can view all available test configuration options through Test Configurations.
import { defineConfig } from '@rstest/core';
export default defineConfig({
- test: {
include: ['**/*.{test,spec}.?(c|m)[jt]s?(x)'],
- environment: 'node',
+ testEnvironment: 'node',
- }
});Rstest uses Rsbuild as the default test build tool instead of Vite. Therefore, you need to migrate your build configuration from Vite configuration to Rstest configuration. You can view all available build configuration options through Build Configurations.
If you need more information about Vite build configuration migration, please refer to Rsbuild - Vite Migration Documentation.
Rstest provides Vitest-compatible APIs. Therefore, you only need to change the import from Vitest to Rstest:
- import { describe, expect, it, test } from 'vitest';
+ import { describe, expect, it, test } from '@rstest/core';Rstest provides the rstest API, which you can use to access Rstest's utility functions, such as rstest.fn() and rstest.mock(). Just like Vitest's vi.fn() and vi.mock(). More utility functions can be found in Rstest APIs.
- const fn = vi.fn();
+ const fn = rstest.fn();
fn.mockResolvedValue('foo');When you need to mock a module's return value, Rstest does not support returning an async function.
As an alternative, Rstest provides synchronous importActual capability, allowing you to import the unmocked module implementation through static import statements:
import * as apiActual from './api' with { rstest: 'importActual' };
// Partially mock the './api' module
rs.mock('./api', () => ({
...apiActual,
fetchUser: rs.fn().mockResolvedValue({ id: 'mocked' }),
}));