> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Testing

Rstack CLI uses [Rstest](https://rstest.rs/) to run tests.

```bash
rs test
```

For command-line options and subcommands, see [`rs test`](/guide/cli/test.md).

## Configure tests

Register an Rstest configuration with [`define.test()`](/guide/configuration.md#define-test). It accepts the same configuration as Rstest's `defineConfig()`:

```ts title="rstack.config.ts"
import { define } from 'rstack';

define.test({
  testEnvironment: 'node',
});
```

## Test APIs

Import test APIs and configuration helpers from [`rstack/test`](/guide/api-reference.md#rstacktest):

```ts
import { defineInlineProject, expect, test } from 'rstack/test';
```

## Configuration inheritance

When `define.test()` does not set Rstest's [`extends`](https://rstest.rs/config/test/extends), Rstack CLI automatically converts the configuration registered by `define.app()` or `define.lib()` into an Rstest configuration. The inherited configuration is merged with the options passed directly to `define.test()`.

### Inherit the application configuration

When `define.app()` is registered, Rstack CLI converts it with [`@rstest/adapter-rsbuild`](https://rstest.rs/guide/integration/rsbuild) and uses the result as the test configuration's `extends` value:

```ts title="rstack.config.ts"
import { define } from 'rstack';

define.app({
  resolve: {
    alias: {
      '@': './src',
    },
  },
});

define.test({
  // Inherits `resolve.alias` from `define.app()`.
  testEnvironment: 'happy-dom',
});
```

### Inherit the library configuration

When `define.lib()` is registered, Rstack CLI converts it with [`@rstest/adapter-rslib`](https://rstest.rs/guide/integration/rslib):

```ts title="rstack.config.ts"
import { define } from 'rstack';

define.lib({
  resolve: {
    alias: {
      '@': './src',
    },
  },
});

define.test({
  // Inherits `resolve.alias` from `define.lib()`.
  testEnvironment: 'node',
});
```

:::tip

When both configurations are registered, Rstack CLI gives `define.app()` precedence.

:::

### Disable automatic inheritance

To keep the test configuration independent, set `extends` explicitly. An empty object disables automatic inheritance without extending another configuration:

```ts title="rstack.config.ts"
import { define } from 'rstack';

define.app({
  resolve: {
    alias: {
      '@': './src',
    },
  },
});

define.test({
  extends: {},
  testEnvironment: 'node',
});
```

For multiple projects, setting `extends` on the root `define.test()` configuration disables automatic inheritance for every project. Setting it on an inline project disables inheritance only for that project.

## Multiple projects

Set Rstest's [`projects`](https://rstest.rs/config/test/projects) option to run multiple test configurations together. Entries can be inline projects or strings that Rstest resolves as external projects.

### Inline projects

Use inline projects when different test environments should share the current application or library configuration:

```ts title="rstack.config.ts"
import { define } from 'rstack';
import { defineInlineProject } from 'rstack/test';

define.app({
  // Shared by both inline projects
});

define.test({
  projects: [
    defineInlineProject({
      name: 'node',
      include: ['./tests/node/**/*.test.ts'],
      testEnvironment: 'node',
    }),
    defineInlineProject({
      name: 'dom',
      include: ['./tests/dom/**/*.test.tsx'],
      testEnvironment: 'happy-dom',
    }),
  ],
});
```

Rstack CLI applies the corresponding adapter to each inline project that omits `extends`. A function-based `define.app()` or `define.lib()` configuration is resolved once, then shared by those inline projects.

Run one project by name:

```bash
rs test --project dom
```

See [`examples/test-inline-projects`](https://github.com/rstackjs/rstack-cli/tree/main/examples/test-inline-projects) for a complete React SSR example using Node.js and happy-dom.

### External projects

Use a string entry for an externally configured project:

```ts title="rstack.config.ts"
import { define } from 'rstack';

define.test({
  projects: ['./legacy/rstest.config.ts'],
});
```

Rstack CLI passes string entries to Rstest unchanged. External projects load their own configuration and do not inherit the current `define.app()` or `define.lib()` configuration. Use external projects when each project manages its configuration independently.
