[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

ci: speed up the ci by parallelising and deduplicating tests (#10683)

authored by

Vladimir and committed by
GitHub
(Jul 1, 2026, 8:12 AM +0200) 313c2aff 33f96a14

+77 -53
+10 -2
.github/actions/setup-playwright/action.yml
··· 33 33 restore-keys: | 34 34 ${{ runner.os }}-playwright- 35 35 36 - - name: Install Playwright Dependencies 36 + # Only Linux needs --with-deps: it apt-installs system libraries the browser 37 + # links against. On Windows --with-deps triggers a slow Media Foundation DISM 38 + # install (~3min) that the tests don't need, and on macOS it is a no-op. 39 + - name: Install Playwright browser with system deps (Linux) 37 40 shell: bash 38 - if: steps.playwright-cache.outputs.cache-hit != 'true' 41 + if: steps.playwright-cache.outputs.cache-hit != 'true' && runner.os == 'Linux' 39 42 run: pnpm exec playwright install --with-deps --only-shell 43 + 44 + - name: Install Playwright browser (macOS/Windows) 45 + shell: bash 46 + if: steps.playwright-cache.outputs.cache-hit != 'true' && runner.os != 'Linux' 47 + run: pnpm exec playwright install --only-shell
+29 -49
.github/workflows/ci.yml
··· 19 19 20 20 env: 21 21 PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright 22 + # Trust the committed lockfile and skip pnpm's per-install supply-chain 23 + # verification (trustPolicy: no-downgrade, ~15-20s on every job). The lint job 24 + # overrides this to false so the lockfile is still verified once per run. 25 + PNPM_CONFIG_TRUST_LOCKFILE: true 22 26 23 27 jobs: 24 28 lint: 25 29 timeout-minutes: 10 26 30 runs-on: ubuntu-latest 27 31 name: 'Lint: node-latest, ubuntu-latest' 32 + # verify the lockfile against supply-chain policies once per run 33 + env: 34 + PNPM_CONFIG_TRUST_LOCKFILE: false 28 35 steps: 29 36 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 30 37 with: ··· 33 40 - uses: ./.github/actions/setup-and-cache 34 41 35 42 - name: Install 36 - run: pnpm i 43 + run: pnpm i --filter '!docs' 37 44 38 45 - name: Build 39 46 run: pnpm run build ··· 110 117 node-version: ${{ matrix.node_version }} 111 118 112 119 - name: Install 113 - run: pnpm i 120 + run: pnpm i --filter '!docs' 114 121 115 122 - uses: ./.github/actions/setup-playwright 116 123 ··· 123 130 VITEST_CI_BLOB_LABEL: ${{ matrix.os }}-node-${{ matrix.node_version }} 124 131 125 132 - name: Test Examples 133 + if: matrix.os == 'ubuntu-latest' 126 134 run: pnpm run test:examples 127 135 128 136 - name: Unit Test UI ··· 149 157 retention-days: 1 150 158 include-hidden-files: true 151 159 152 - test-cached: 153 - needs: changed 154 - name: 'Cache&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}' 155 - if: needs.changed.outputs.should_skip != 'true' 156 - runs-on: ${{ matrix.os }} 157 - 158 - timeout-minutes: 30 159 - 160 - strategy: 161 - matrix: 162 - node_version: [24] 163 - os: 164 - - macos-latest 165 - - windows-latest 166 - fail-fast: false 167 - 168 - steps: 169 - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 170 - with: 171 - persist-credentials: false 172 - 173 - - uses: ./.github/actions/setup-and-cache 174 - with: 175 - node-version: ${{ matrix.node_version }} 176 - 177 - - name: Install 178 - run: pnpm i 179 - 180 - - uses: ./.github/actions/setup-playwright 181 - 182 - - name: Build 183 - run: pnpm run build 184 - 185 - - name: Test 186 - run: pnpm run test:ci:cache 187 - 188 160 test-browser: 189 161 needs: changed 190 162 name: 'Browsers: node-${{ matrix.node_version }}, ${{ matrix.os }}' ··· 211 183 node-version: ${{ matrix.node_version }} 212 184 213 185 - name: Install 214 - run: pnpm i 186 + run: pnpm i --filter '!docs' 215 187 216 188 - uses: ./.github/actions/setup-playwright 217 189 ··· 224 196 test-vite7: 225 197 needs: changed 226 198 # macos-latest is the fastest one 227 - name: 'Test: vite@7, node-24, macos-latest' 199 + name: 'Test: vite@7, ${{ matrix.suite }}, node-24, macos-latest' 228 200 if: needs.changed.outputs.should_skip != 'true' 229 201 runs-on: macos-latest 230 202 231 203 timeout-minutes: 30 204 + 205 + strategy: 206 + # split the node suite and the browser suite onto separate runners so they 207 + # run in parallel instead of sequentially on a single machine 208 + matrix: 209 + suite: [node, browser] 210 + fail-fast: false 232 211 233 212 steps: 234 213 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 ··· 242 221 - name: Install 243 222 run: | 244 223 pnpm override-vite7 245 - git add . && git commit -m "ci" && pnpm i --prefer-offline --no-frozen-lockfile 224 + git add . && git commit -m "ci" && pnpm i --prefer-offline --no-frozen-lockfile --filter '!docs' 246 225 247 226 - uses: ./.github/actions/setup-playwright 248 227 ··· 250 229 run: pnpm run build 251 230 252 231 - name: Test 232 + if: ${{ matrix.suite == 'node' }} 253 233 run: pnpm run test:ci:no-bail 254 234 255 235 - name: Test Examples 256 - if: ${{ !cancelled() }} 236 + if: ${{ matrix.suite == 'node' && !cancelled() }} 257 237 run: pnpm run test:examples 258 238 259 239 - name: Unit Test UI 260 - if: ${{ !cancelled() }} 240 + if: ${{ matrix.suite == 'node' && !cancelled() }} 261 241 run: pnpm -C packages/ui test:ui 262 242 263 - - name: Test Browser (playwright) 264 - if: ${{ !cancelled() }} 265 - run: pnpm run test:browser:playwright 266 - 267 243 - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 268 - if: ${{ !cancelled() }} 244 + if: ${{ matrix.suite == 'node' && !cancelled() }} 269 245 with: 270 246 name: playwright-report-vite7 271 247 path: test/ui/test-results/ 272 248 retention-days: 30 249 + 250 + - name: Test Browser (playwright) 251 + if: ${{ matrix.suite == 'browser' && !cancelled() }} 252 + run: pnpm run test:browser:playwright 273 253 274 254 merge-reports: 275 255 needs: ··· 287 267 - uses: ./.github/actions/setup-and-cache 288 268 289 269 - name: Install 290 - run: pnpm i 270 + run: pnpm i --filter '!docs' 291 271 292 272 - name: Build 293 273 run: pnpm run build
-1
package.json
··· 26 26 "test": "pnpm --filter test-unit test:threads", 27 27 "test:ci": "CI=true pnpm -r --reporter-hide-prefix --stream --sequential --filter '@vitest/test-*' --filter !test-browser run test", 28 28 "test:ci:no-bail": "CI=true pnpm -r --no-bail --reporter-hide-prefix --stream --sequential --filter '@vitest/test-*' --filter !test-browser run test", 29 - "test:ci:cache": "CI=true pnpm -r --reporter-hide-prefix --stream --sequential --filter '@vitest/test-*' --filter !test-browser --filter '!@vitest/test-integration-dts-*' --filter !test-ui --filter !test-cache run test --experimental.fsModuleCache", 30 29 "test:examples": "CI=true pnpm -r --reporter-hide-prefix --stream --filter '@vitest/example-*' run test", 31 30 "test:ecosystem-ci": "ECOSYSTEM_CI=true pnpm test:ci", 32 31 "typebuild": "tsx ./scripts/explain-types.ts",
+3
test/coverage-test/vitest.config.ts
··· 12 12 13 13 export default defineConfig({ 14 14 test: { 15 + experimental: { 16 + fsModuleCache: true, 17 + }, 15 18 reporters: process.env.CI ? 'minimal' : 'verbose', 16 19 isolate: false, 17 20 setupFiles: ['./setup.ts'],
+29 -1
test/e2e/vitest.config.ts
··· 2 2 import { defineConfig } from 'vite' 3 3 import { defaultExclude } from 'vitest/config' 4 4 5 + // Tests that drive git `--changed` against shared fixtures and cannot tolerate 6 + // other tests mutating the working tree concurrently. Run in a serial project. 7 + const serialTests = [ 8 + 'test/git-changed.test.ts', 9 + 'test/list-changed.test.ts', 10 + 'test/setup-files.test.ts', 11 + 'test/watch/related.test.ts', 12 + ] 13 + 5 14 export default defineConfig({ 6 15 test: { 16 + experimental: { 17 + fsModuleCache: true, 18 + }, 7 19 reporters: [ 8 20 process.env.CI ? 'minimal' : 'verbose', 9 21 (process.env.VITEST_CI_BLOB_LABEL ··· 24 36 test: { 25 37 name: 'main', 26 38 include: ['test/**/**.{test,spec}.ts'], 39 + exclude: [...defaultExclude, ...serialTests], 27 40 includeTaskLocation: true, 28 41 testTimeout: 60_000, 29 42 isolate: false, 30 - fileParallelism: false, 43 + fileParallelism: true, 44 + maxWorkers: 2, 31 45 // TODO: should enabled when support for older node is dropped? 32 46 // experimental: { 33 47 // viteModuleRunner: false, ··· 58 72 testTimeout: process.env.CI ? 20_000 : undefined, 59 73 sequence: { 60 74 groupOrder: 1, 75 + }, 76 + }, 77 + }, 78 + { 79 + extends: true, 80 + test: { 81 + name: 'serial', 82 + include: serialTests, 83 + includeTaskLocation: true, 84 + testTimeout: 60_000, 85 + isolate: false, 86 + fileParallelism: false, 87 + sequence: { 88 + groupOrder: 2, 61 89 }, 62 90 }, 63 91 },
+5
test/test-utils/index.ts
··· 139 139 throw new Error(`Don't pass down "viteConfig" with "test" property. Use the rest of the first argument.`) 140 140 } 141 141 142 + // Don't let unrelated package.json / config edits made by other tests running 143 + // in parallel force-rerun this test's watcher. Applied as a default here so a 144 + // fixture config or an explicit `forceRerunTriggers` still takes precedence. 145 + rest.forceRerunTriggers ??= [] 146 + 142 147 ;(viteConfig as any).test = rest 143 148 144 149 try {
+1
tsconfig.check.json
··· 14 14 "./packages/*/*.d.ts", 15 15 "./packages/*/*.d.cts", 16 16 "./examples/**/*.*", 17 + "./docs/**", 17 18 "./bench/**", 18 19 "./test/e2e/**", 19 20 "./test/typescript/**",