Rstest Documentation
website·Indexed 33 days ago
https://rstest.rsA JavaScript and TypeScript testing framework powered by Rspack and Rsbuild. It features a bundle-based execution model for fast performance, first-class support for the Rspack ecosystem, and an experimental Browser Mode for running tests in real browsers. The framework includes support for mocking, snapshot testing, E2E testing with Playwright, and provides migration guides for users moving from Jest and Vitest.
What's inside Rstest
- Rstest is a JavaScript testing framework powered by Rspack. It provides Jest-compatible APIs and native support for TypeScript, ESM, CJS, and CSS Modules. Unlike traditional per-file transform-and-execute frameworks, Rstest uses a dependency graph-based bundle model. This allows it to leverage build-time optimizations like tree-shaking and skipping unused re-exports, making test behavior more consistent with production output and improving performance in large-scale projects.
Overview of Rstest testing framework
Rstest is a JavaScript and TypeScript testing framework built on Rsbuild and Rspack. It uses a bundle-based execution model leveraging Rspack's Rust-based build pipeline and SWC transforms for fast test compilation. It allows developers to reuse existing build configurations and run tests across Node.js, simulated DOM environments, and real browsers.Overview of built-in Rstest reporters
Rstest provides several built-in reporters for different environments and needs:
default: Console output with colors; ideal for local development.dot: Compact per-test markers (·pass,xfail,-skip,*todo); fast local feedback.verbose: Detailed output for all test cases; useful for debugging.github-actions: CI error annotations and Markdown summaries for GitHub Actions.junit: JUnit XML format for CI/CD integration.json: Structured JSON report for tooling and scripting.md: Markdown agent report for LLM/Agent integrations.blob: Serialized JSON output for merging sharded reports.
Overview of Rstest Testing Framework
Rstest is a testing framework based on Rspack that provides first-class support for the Rspack ecosystem. It allows developers to reuse existing Rsbuild or Rspack configurations, ensuring that aliases, transforms, and plugins remain consistent between the development build and the test environment. By running tests through Rspack's bundling model, it closely matches production behavior while maintaining fast startup and rerun speeds. It supports TypeScript, ESM, CJS, CSS Modules, and modern JavaScript out of the box, and includes built-in assertions, snapshots, mocks, coverage, and lifecycle hooks.Overview of Rstest Adapters
Adapters in Rstest allow developers to convert configurations from other tools (like build tools or CLIs) into a format Rstest supports. This enables the reuse of existing configurations (e.g., path aliases, global variables), simplifies maintenance by centralizing configuration, and allows frameworks to provide preset test environments.Overview of the Rstack JavaScript toolchain
Rstack is a fast, unified JavaScript toolchain designed for developers and AI agents. It consists of several high-performance, Rust-based tools aimed at modernizing the web development workflow:Overview of Rstest Browser Mode
Browser Mode allows tests to execute in real browsers (Chromium, Firefox, or WebKit) using Playwright, ensuring that tests run with the exact same browser APIs and behaviors as in production. This is recommended over simulated environments like jsdom or happy-dom when you need full Browser API coverage, native support for Canvas/WebGL and Web Workers, real CSS computed styles, or cross-browser testing.
Note: Like Node mode, Browser Mode will fail a test file if an unhandled error or promise rejection escapes the file, even if all individual tests passed. Always
awaitpromises or attach handlers to prevent leaks.Understand Rstest's bundle-based execution model
Rstest uses a bundle-based execution model where files in the bundle graph are transformed by the build pipeline (supporting TypeScript, JSX, and aliases). However, some code is loaded by Node.js at runtime and preserves native Node.js semantics. This includes late dynamic
require()orimport()calls, externalized modules, and code loaded via custom Node.js loaders or register hooks.Rule of thumb:
- Static imports in the bundle graph: Rstest transforms/bundles them.
- Dynamic loads, loader hooks, and externalized modules: Expect native Node.js behavior.
Use TestContext for runtime test control and metadata
The
TestContextobject is available in tests, hooks, and fixtures. It provides:task: Metadata about the current test, includingid,name,filepath,projectRoot,retryCount(0 for initial attempt), and a mutablemetaobject for custom JSON-serializable data.signal: AnAbortSignalthat triggers when the test attempt times out. Pass this to async APIs (likefetchorfs.readFile) to cancel pending work.skip(): A method to immediately skip the current test during execution.expect: The bound assertion API.
import { test } from '@rstest/core'; import { readFile } from 'node:fs/promises'; test('runtime context example', async ({ signal, task }) => { // 1. Use signal for cancellation await readFile('./large-data.json', { signal }); // 2. Attach custom metadata to the result task.meta.coveredBranches = ['a', 'b']; // 3. Conditional skip if (someCondition) { test.skip(); } });Rstest Test API Overview
The Rstest Test API provides the core primitives for defining and executing tests. It includes:
expect: The assertion library for validating outcomes, featuring soft assertions (expect.soft), polling (expect.poll), and various matchers (common, mock, snapshot, promise, and asymmetric).test: The primary function for defining test cases, with modifiers for isolation (test.only), skipping (test.skip,test.skipIf), requirements (test.todo), and execution mode (test.concurrent,test.sequential).describe: Used to group related tests, supporting similar modifiers astest(e.g.,describe.only,describe.skip,describe.each).Hooks: Lifecycle methods to manage setup and teardown, includingbeforeAll,afterAll,beforeEach,afterEach,onTestFinished, andonTestFailed.
Use Locator for element querying and interaction
Locatoris the core API for element querying and interaction in Browser Mode. The typical workflow involves using thepageobject to locate elements, performing interactions on the resultingLocator, and usingexpect.elementfor assertions. When using the Playwright provider, interaction methods (likeclick,fill,check) automatically wait for elements to become actionable (visible, enabled, stable) before executing.import { page } from '@rstest/browser'; import { expect, test } from '@rstest/core'; test('interacts with a form using locator', async () => { await page.getByLabel('Username').fill('alice'); await page.getByLabel('Password').fill('secret123'); await page.getByRole('button', { name: 'Login' }).click(); await expect.element(page.getByLabel('Username')).toHaveValue('alice'); });Perform cleanup regardless of test result with onTestFinished
The
onTestFinishedhook is called after a test finishes, regardless of whether it passed or failed. It executes afterafterEach.Important for Concurrent Tests: When using
describe.concurrent, do not use the globalonTestFinishedimport. Instead, retrieveonTestFinishedfrom the test context to ensure the hook is associated with the correct test.import { onTestFinished, test } from '@rstest/core'; // Standard usage test('test server', () => { const server = startServer(); onTestFinished(() => server.close()); }); // Concurrent usage describe.concurrent('concurrent suite', () => { test('test 1', async ({ onTestFinished }) => { onTestFinished(() => { /* cleanup */ }); }); });