|
| 1 | +# Testing |
| 2 | + |
| 3 | +Rstack uses [Rstest](https://rstest.rs/) to run tests. |
| 4 | + |
| 5 | +```bash |
| 6 | +rs test |
| 7 | +``` |
| 8 | + |
| 9 | +For command-line options and subcommands, see [`rs test`](./cli/test). |
| 10 | + |
| 11 | +## Configure tests |
| 12 | + |
| 13 | +Register an Rstest configuration with [`define.test()`](./configuration#define-test). It accepts the same configuration as Rstest's `defineConfig()`: |
| 14 | + |
| 15 | +```ts title="rstack.config.ts" |
| 16 | +import { define } from 'rstack'; |
| 17 | + |
| 18 | +define.test({ |
| 19 | + testEnvironment: 'node', |
| 20 | +}); |
| 21 | +``` |
| 22 | + |
| 23 | +## Test APIs |
| 24 | + |
| 25 | +Import test APIs and configuration helpers from [`rstack/test`](./api-reference#rstacktest): |
| 26 | + |
| 27 | +```ts |
| 28 | +import { defineInlineProject, expect, test } from 'rstack/test'; |
| 29 | +``` |
| 30 | + |
| 31 | +## Single project |
| 32 | + |
| 33 | +For a single test project, pass the Rstest options directly to `define.test()`: |
| 34 | + |
| 35 | +```ts title="rstack.config.ts" |
| 36 | +import { define } from 'rstack'; |
| 37 | + |
| 38 | +define.app({ |
| 39 | + // Shared application configuration |
| 40 | +}); |
| 41 | + |
| 42 | +define.test({ |
| 43 | + testEnvironment: 'happy-dom', |
| 44 | +}); |
| 45 | +``` |
| 46 | + |
| 47 | +When `extends` is omitted, Rstack uses the Rsbuild adapter to extend the test configuration from `define.app()`. If no application configuration is defined, it uses the Rslib adapter with `define.lib()` instead. `define.app()` takes precedence when both are defined. |
| 48 | + |
| 49 | +## Multiple projects |
| 50 | + |
| 51 | +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. |
| 52 | + |
| 53 | +### Inline projects |
| 54 | + |
| 55 | +Use inline projects when different test environments should share the current application or library configuration: |
| 56 | + |
| 57 | +```ts title="rstack.config.ts" |
| 58 | +import { define } from 'rstack'; |
| 59 | +import { defineInlineProject } from 'rstack/test'; |
| 60 | + |
| 61 | +define.app({ |
| 62 | + // Shared by both inline projects |
| 63 | +}); |
| 64 | + |
| 65 | +define.test({ |
| 66 | + projects: [ |
| 67 | + defineInlineProject({ |
| 68 | + name: 'node', |
| 69 | + include: ['./tests/node/**/*.test.ts'], |
| 70 | + testEnvironment: 'node', |
| 71 | + }), |
| 72 | + defineInlineProject({ |
| 73 | + name: 'dom', |
| 74 | + include: ['./tests/dom/**/*.test.tsx'], |
| 75 | + testEnvironment: 'happy-dom', |
| 76 | + }), |
| 77 | + ], |
| 78 | +}); |
| 79 | +``` |
| 80 | + |
| 81 | +Rstack 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. |
| 82 | + |
| 83 | +Run one project by name: |
| 84 | + |
| 85 | +```bash |
| 86 | +rs test --project dom |
| 87 | +``` |
| 88 | + |
| 89 | +See [`examples/rstest-inline-projects`](https://github.com/rstackjs/rstack-cli/tree/main/examples/rstest-inline-projects) for a complete React SSR example using Node.js and happy-dom. |
| 90 | + |
| 91 | +### External projects |
| 92 | + |
| 93 | +Use a string entry for an externally configured project: |
| 94 | + |
| 95 | +```ts title="rstack.config.ts" |
| 96 | +import { define } from 'rstack'; |
| 97 | + |
| 98 | +define.test({ |
| 99 | + projects: ['./legacy/rstest.config.ts'], |
| 100 | +}); |
| 101 | +``` |
| 102 | + |
| 103 | +Rstack 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. |
| 104 | + |
| 105 | +## Customize inheritance |
| 106 | + |
| 107 | +Set Rstest's [`extends`](https://rstest.rs/config/test/extends) option explicitly when a project should not inherit the current application or library configuration: |
| 108 | + |
| 109 | +```ts title="rstack.config.ts" |
| 110 | +import { define } from 'rstack'; |
| 111 | +import { defineInlineProject } from 'rstack/test'; |
| 112 | + |
| 113 | +define.test({ |
| 114 | + projects: [ |
| 115 | + defineInlineProject({ |
| 116 | + name: 'standalone', |
| 117 | + extends: { |
| 118 | + testEnvironment: 'node', |
| 119 | + }, |
| 120 | + }), |
| 121 | + ], |
| 122 | +}); |
| 123 | +``` |
| 124 | + |
| 125 | +Setting `extends` on an inline project disables automatic inheritance only for that project. Setting it on the root `define.test()` configuration disables automatic inheritance for the entire test configuration. |
0 commit comments