### Example Setup File Content Source: https://vitest.dev/guide/learn/setup-teardown An example setup file that extends Vitest's `expect` API with custom matchers. Setup files run before test files are collected. ```js // This runs before every test file import { expect } from 'vitest' import { customMatchers } from './custom-matchers.js' expect.extend(customMatchers) ``` -------------------------------- ### Complex Fixture Setup and Cleanup Source: https://vitest.dev/guide/test-context This example shows how to manage more complex setup and cleanup for fixtures, including database connections and user creation/deletion. ```typescript const test = baseTest .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => { const db = await createDatabase() await db.connect() onCleanup(async () => { await db.disconnect() }) return db }) .extend('user', async ({ database }, { onCleanup }) => { const user = await database.createTestUser() onCleanup(async () => { await database.deleteUser(user.id) }) return user }) ``` -------------------------------- ### Install Vitest with bun Source: https://vitest.dev/guide Install Vitest as a development dependency using bun. ```bash bun add -D vitest ``` -------------------------------- ### Install Preview Provider Source: https://vitest.dev/guide/browser Install the preview provider for local testing and visual inspection. ```npm npm install -D vitest @vitest/browser-preview ``` ```yarn yarn add -D vitest @vitest/browser-preview ``` ```pnpm pnpm add -D vitest @vitest/browser-preview ``` ```bun bun add -D vitest @vitest/browser-preview ``` -------------------------------- ### Global Setup and Teardown in Vitest Source: https://vitest.dev/guide/lifecycle Defines setup and teardown functions for global lifecycle hooks. The setup function can provide data to tests using `project.provide()`. Runs once before all tests. ```typescript export function setup(project) { // Runs once before all tests console.log('Global setup') // Share data with tests project.provide('apiUrl', 'http://localhost:3000') } export function teardown() { // Runs once after all tests console.log('Global teardown') } ``` -------------------------------- ### Install Vitest UI Source: https://vitest.dev/guide/ui Install the Vitest UI as a development dependency using npm. ```bash npm i -D @vitest/ui ``` -------------------------------- ### Install Vitest with pnpm Source: https://vitest.dev/guide Install Vitest as a development dependency using pnpm. ```bash pnpm add -D vitest ``` -------------------------------- ### Create a Vitest instance Source: https://vitest.dev/guide/advanced Initializes a Vitest instance without starting tests or validating installed packages. ```js import { createVitest } from 'vitest/node' const vitest = await createVitest('test', { watch: false, }) ``` -------------------------------- ### Setup File with Global Hooks in Vitest Source: https://vitest.dev/guide/lifecycle A setup file that runs before each test file. It can initialize global state and register hooks that apply to all tests, such as `afterEach`. ```typescript import { afterEach } from 'vitest' // Runs before each test file console.log('Setup file executing') // Register hooks that apply to all tests afterEach(() => { cleanup() }) ``` -------------------------------- ### Vitest Test Execution Flow Example Source: https://vitest.dev/guide/lifecycle Demonstrates the order of execution for file-level code, describe blocks, and various hooks within a single test file. Useful for understanding setup and teardown phases. ```typescript // This runs immediately (collection phase) console.log('File loaded') describe('User API', () => { // This runs immediately (collection phase) console.log('Suite defined') aroundAll(async (runSuite) => { // Wraps around all tests in this suite console.log('aroundAll before') await runSuite() console.log('aroundAll after') }) beforeAll(() => { // Runs once before all tests in this suite console.log('beforeAll') }) aroundEach(async (runTest) => { // Wraps around each test console.log('aroundEach before') await runTest() console.log('aroundEach after') }) beforeEach(() => { // Runs before each test console.log('beforeEach') }) test('creates user', () => { // Test executes console.log('test 1') }) test('updates user', () => { // Test executes console.log('test 2') }) afterEach(() => { // Runs after each test console.log('afterEach') }) afterAll(() => { // Runs once after all tests in this suite console.log('afterAll') }) }) ``` -------------------------------- ### Configure Setup Files in Vitest Config Source: https://vitest.dev/guide/learn/setup-teardown Specify setup files in `vitest.config.js` to run initialization code before every test file. This is suitable for polyfills or global configuration. ```js import { defineConfig } from 'vitest/config' export default defineConfig({ test: { setupFiles: ['./test/setup.js'], }, }) ``` -------------------------------- ### Install Playwright Provider Source: https://vitest.dev/guide/browser Install the Playwright provider for robust CI and parallel test execution. ```npm npm install -D vitest @vitest/browser-playwright ``` ```yarn yarn add -D vitest @vitest/browser-playwright ``` ```pnpm pnpm add -D vitest @vitest/browser-playwright ``` ```bun bun add -D vitest @vitest/browser-playwright ``` -------------------------------- ### Install Vitest with npm Source: https://vitest.dev/guide Install Vitest as a development dependency using npm. ```bash npm install -D vitest ``` -------------------------------- ### Install WebdriverIO Provider Source: https://vitest.dev/guide/browser Install the WebdriverIO provider to run tests using the WebDriver protocol. ```npm npm install -D vitest @vitest/browser-webdriverio ``` ```yarn yarn add -D vitest @vitest/browser-webdriverio ``` ```pnpm pnpm add -D vitest @vitest/browser-webdriverio ``` ```bun bun add -D vitest @vitest/browser-webdriverio ``` -------------------------------- ### Install Vitest with yarn Source: https://vitest.dev/guide Install Vitest as a development dependency using yarn. ```bash yarn add -D vitest ``` -------------------------------- ### Setup Zsh shell autocompletions Source: https://vitest.dev/guide/cli Add the provided source command to your `~/.zshrc` file for permanent shell autocompletion setup in Zsh. ```bash # Add to ~/.zshrc for permanent autocompletions (same can be done for other shells) source <(vitest complete zsh) ``` -------------------------------- ### Initialize Browser Mode Source: https://vitest.dev/guide/browser Use the CLI to automatically install dependencies and configure browser mode. ```npm npx vitest init browser ``` ```yarn yarn exec vitest init browser ``` ```pnpm pnpx vitest init browser ``` ```bun bunx vitest init browser ``` -------------------------------- ### Install Istanbul Coverage Support Source: https://vitest.dev/guide/coverage Install the necessary package for Istanbul coverage support using npm. ```bash npm i -D @vitest/coverage-istanbul ``` -------------------------------- ### Configure MSW for HTTP, GraphQL, and WebSocket Source: https://vitest.dev/guide/mocking/requests Setup server lifecycle hooks in a Vitest setup file to handle network requests. Using 'onUnhandledRequest: error' ensures tests fail if a request lacks a defined handler. ```js import { afterAll, afterEach, beforeAll } from 'vitest' import { setupServer } from 'msw/node' import { http, HttpResponse } from 'msw' const posts = [ { userId: 1, id: 1, title: 'first post title', body: 'first post body', }, // ... ] export const restHandlers = [ http.get('https://rest-endpoint.example/path/to/posts', () => { return HttpResponse.json(posts) }), ] const server = setupServer(...restHandlers) // Start server before all tests beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) // Close server after all tests afterAll(() => server.close()) // Reset handlers after each test for test isolation afterEach(() => server.resetHandlers()) ``` ```js import { afterAll, afterEach, beforeAll } from 'vitest' import { setupServer } from 'msw/node' import { graphql, HttpResponse } from 'msw' const posts = [ { userId: 1, id: 1, title: 'first post title', body: 'first post body', }, // ... ] const graphqlHandlers = [ graphql.query('ListPosts', () => { return HttpResponse.json({ data: { posts }, }) }), ] const server = setupServer(...graphqlHandlers) // Start server before all tests beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) // Close server after all tests afterAll(() => server.close()) // Reset handlers after each test for test isolation afterEach(() => server.resetHandlers()) ``` ```js import { afterAll, afterEach, beforeAll } from 'vitest' import { setupServer } from 'msw/node' import { ws } from 'msw' const chat = ws.link('wss://chat.example.com') const wsHandlers = [ chat.addEventListener('connection', ({ client }) => { client.addEventListener('message', (event) => { console.log('Received message from client:', event.data) // Echo the received message back to the client client.send(`Server received: ${event.data}`) }) }), ] const server = setupServer(...wsHandlers) // Start server before all tests beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) // Close server after all tests afterAll(() => server.close()) // Reset handlers after each test for test isolation afterEach(() => server.resetHandlers()) ``` -------------------------------- ### startVitest Source: https://vitest.dev/guide/advanced Starts the Vitest test runner programmatically. ```APIDOC ## startVitest ### Description Starts running Vitest tests using the Node API. Returns a Vitest instance. ### Parameters - **mode** (VitestRunMode) - Required - The run mode (e.g., 'test'). - **cliFilters** (string[]) - Optional - List of file path filters. - **options** (CliOptions) - Optional - CLI arguments to override test config. - **viteOverrides** (ViteUserConfig) - Optional - Complete Vite config. - **vitestOptions** (VitestOptions) - Optional - Additional Vitest specific options. ### Request Example ```js import { startVitest } from 'vitest/node' const vitest = await startVitest('test') await vitest.close() ``` ``` -------------------------------- ### Initiate and run tests with startVitest Source: https://vitest.dev/guide/advanced/tests Starts Vitest, validates dependencies, and executes tests immediately. ```ts import { startVitest } from 'vitest/node' const vitest = await startVitest( 'test', [], // CLI filters {}, // override test config {}, // override Vite config {}, // custom Vitest options ) const testModules = vitest.state.getTestModules() for (const testModule of testModules) { console.log(testModule.moduleId, testModule.ok() ? 'passed' : 'failed') } ``` -------------------------------- ### Example TAP Report Output Source: https://vitest.dev/guide/reporters An example of the output format generated by the TAP reporter. ```bash TAP version 13 1..1 not ok 1 - __tests__/test-file-1.test.ts # time=14.00ms { 1..1 not ok 1 - first test file # time=13.00ms { 1..2 not ok 1 - 2 + 2 should equal 4 # time=11.00ms --- error: name: "AssertionError" message: "expected 5 to be 4 // Object.is equality" at: "/root-directory/__tests__/test-file-1.test.ts:20:28" actual: "5" expected: "4" ... ok 2 - 4 - 2 should equal 2 # time=1.00ms } } ``` -------------------------------- ### Configure Different Browser Setups with Custom Options Source: https://vitest.dev/guide/browser/multiple-setups Define distinct configurations for browser instances, including custom setup files and injected values using the `provide` field. This allows for varied test environments within the same browser. ```typescript import { defineConfig } from 'vitest/config' import { playwright } from '@vitest/browser-playwright' export default defineConfig({ test: { browser: { enabled: true, provider: playwright(), headless: true, instances: [ { browser: 'chromium', name: 'chromium-1', setupFiles: ['./ratio-setup.ts'], provide: { ratio: 1, }, }, { browser: 'chromium', name: 'chromium-2', provide: { ratio: 2, }, }, ], }, }, }) ``` ```typescript import { expect, inject, test } from 'vitest' import { globalSetupModifier } from './example.js' test('ratio works', () => { expect(inject('ratio') * globalSetupModifier).toBe(14) }) ``` -------------------------------- ### Repeating Setup/Teardown for Each Test Source: https://vitest.dev/guide/learn/setup-teardown Use `beforeEach` and `afterEach` to ensure each test starts with a clean state. This is ideal for initializing or resetting data before and after every test. ```javascript import { afterEach, beforeEach, expect, test } from 'vitest' let items beforeEach(() => { items = ['apple', 'banana', 'cherry'] }) afterEach(() => { items = [] }) test('items starts with 3 fruits', () => { expect(items).toHaveLength(3) }) test('can add an item', () => { items.push('date') expect(items).toHaveLength(4) // afterEach will reset items for the next test, // so this mutation won't leak into other tests }) ``` -------------------------------- ### Object Syntax Fixture Setup and Cleanup Source: https://vitest.dev/guide/test-context Use the `use()` callback pattern for fixture setup and cleanup in object syntax. The cleanup code runs after the test function has completed. ```typescript import { test as baseTest } from 'vitest' export const test = baseTest.extend({ page: async ({}, use) => { // setup the fixture before each test function const page = await browser.newPage() // use the fixture value await use(page) // cleanup the fixture after each test function await page.close() }, baseUrl: 'http://localhost:3000' }) ``` -------------------------------- ### Define a Custom Vitest Environment Source: https://vitest.dev/guide/environment Create a custom environment by exporting an object conforming to the `Environment` interface. This example shows a basic custom environment named 'custom' that uses Vite's 'ssr' environment and includes optional `setupVM` and `setup` functions for environment-specific initialization and teardown. ```typescript import type { Environment } from 'vitest/runtime' export default { name: 'custom', viteEnvironment: 'ssr', // optional - only if you support "vmForks" or "vmThreads" pools async setupVM() { const vm = await import('node:vm') const context = vm.createContext() return { getVmContext() { return context }, teardown() { // called after all tests with this env have been run } } }, setup() { // custom setup return { teardown() { // called after all tests with this env have been run } } } } ``` -------------------------------- ### Install DOM Mocking Libraries Source: https://vitest.dev/guide/features Install either `happy-dom` or `jsdom` as development dependencies to mock DOM and browser APIs for your tests. ```bash $ npm i -D happy-dom ``` ```bash $ npm i -D jsdom ``` -------------------------------- ### Install V8 Coverage Support Source: https://vitest.dev/guide/coverage Install the necessary package for V8 coverage support using npm. ```bash npm i -D @vitest/coverage-v8 ``` -------------------------------- ### Istanbul Coverage Instrumentation Example Source: https://vitest.dev/guide/coverage Illustrates how Istanbul instruments source files by adding coverage counters for branches and functions. This example is simplified and specific to Vitest's internal representation. ```js // Simplified example of branch and function coverage counters const coverage = { // [!code ++] branches: { 1: [0, 0] }, // [!code ++] functions: { 1: 0 }, // [!code ++] } // [!code ++] export function getUsername(id) { // Function coverage increased when this is invoked // [!code ++] coverage.functions['1']++ // [!code ++] if (id == null) { // Branch coverage increased when this is invoked // [!code ++] coverage.branches['1'][0]++ // [!code ++] throw new Error('User ID is required') } // Implicit else coverage increased when if-statement condition not met // [!code ++] coverage.branches['1'][1]++ // [!code ++] return database.getUser(id) } globalThis.__VITEST_COVERAGE__ ||= {} globalThis.__VITEST_COVERAGE__[filename] = coverage ``` -------------------------------- ### startVitest API Source: https://vitest.dev/guide/advanced/tests The `startVitest` function initiates Vitest, validates package installations, and immediately runs tests. It returns a Vitest instance that can be used to access test module information. ```APIDOC ## `startVitest` ### Description Initiates Vitest, validates packages, and runs tests immediately. ### Method `startVitest(cliFilter: string, cliArgs: string[], vitestConfigOverride: object, viteConfigOverride: object, customVitestOptions: object): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ts import { startVitest } from 'vitest/node' const vitest = await startVitest( 'test', // CLI filters [], // CLI args {}, // override test config {}, // override Vite config {}, // custom Vitest options ) const testModules = vitest.state.getTestModules() for (const testModule of testModules) { console.log(testModule.moduleId, testModule.ok() ? 'passed' : 'failed') } ``` ### Response #### Success Response (200) - **vitest** (VitestInstance) - An instance of Vitest with tests executed. #### Response Example ```json { "testModules": [ { "moduleId": "path/to/test.spec.ts", "status": "passed" }, { "moduleId": "path/to/another.test.js", "status": "failed" } ] } ``` ``` -------------------------------- ### Example source file for spying Source: https://vitest.dev/guide/mocking/modules A sample module demonstrating how named exports are consumed by other functions. ```js import { answer } from './example.js' export function question() { if (answer() === 42) { return 'Ultimate Question of Life, the Universe, and Everything' } return 'Unknown Question' } ``` -------------------------------- ### Configure OpenTelemetry SDK and Vitest Source: https://vitest.dev/guide/open-telemetry Setup the OpenTelemetry SDK module and register it within the Vitest configuration file. ```js import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto' import { NodeSDK } from '@opentelemetry/sdk-node' const sdk = new NodeSDK({ serviceName: 'vitest', traceExporter: new OTLPTraceExporter(), instrumentations: [getNodeAutoInstrumentations()], }) sdk.start() export default sdk ``` ```js import { defineConfig } from 'vitest/config' export default defineConfig({ test: { experimental: { openTelemetry: { enabled: true, sdkPath: './otel.js', }, }, }, }) ``` -------------------------------- ### Install Browser OpenTelemetry dependencies Source: https://vitest.dev/guide/open-telemetry Required packages for capturing traces from the browser runtime. ```shell npm i @opentelemetry/sdk-trace-web @opentelemetry/exporter-trace-otlp-proto ``` -------------------------------- ### Setup Chrome for WebdriverIO in CI Source: https://vitest.dev/guide/browser/visual-regression-testing Integrate the `browser-actions/setup-chrome` action into your GitHub Actions workflow to ensure Chrome is available for WebdriverIO tests. ```yaml # ...the rest of the workflow - uses: browser-actions/setup-chrome@v1 with: chrome-version: 120 ``` -------------------------------- ### Example Vitest test file Source: https://vitest.dev/guide A basic Vitest test file that imports and tests the 'sum' function. ```js import { expect, test } from 'vitest' import { sum } from './sum.js' test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3) }) ``` -------------------------------- ### Setup Custom Snapshot Matchers Source: https://vitest.dev/guide/snapshot Extend Vitest's expect with custom snapshot matchers using a provided adapter. This setup allows for domain-specific snapshot comparisons. ```typescript import { expect, Snapshots } from 'vitest' import { kvAdapter } from './kv-adapter' expect.extend({ toMatchKvSnapshot(received: unknown) { return Snapshots.toMatchDomainSnapshot.call(this, kvAdapter, received) }, toMatchKvInlineSnapshot(received: unknown, inlineSnapshot?: string) { return Snapshots.toMatchDomainInlineSnapshot.call(this, kvAdapter, received, inlineSnapshot) }, }) ``` -------------------------------- ### Tag Resolution Examples Source: https://vitest.dev/guide/test-tags Demonstrates how tag options are merged based on priority and explicit test-level overrides. ```ts test('flaky database test', { tags: ['flaky', 'db'] }) // { timeout: 30_000, retry: 3 } ``` ```ts test('flaky database test', { tags: ['flaky', 'db'], timeout: 120_000 }) // { timeout: 120_000, retry: 3 } ``` -------------------------------- ### Define custom package conditions Source: https://vitest.dev/guide/common-errors Example configuration for package.json exports and imports to support custom conditions. ```json { "exports": { ".": { "custom": "./lib/custom.js", "import": "./lib/index.js" } }, "imports": { "#internal": { "custom": "./src/internal.js", "default": "./lib/internal.js" } } } ``` -------------------------------- ### Example TAP Flat Report Output Source: https://vitest.dev/guide/reporters Demonstrates the output format of the TAP Flat reporter, which presents test results as a flat list. ```bash TAP version 13 1..2 not ok 1 - __tests__/test-file-1.test.ts > first test file > 2 + 2 should equal 4 # time=11.00ms --- error: name: "AssertionError" message: "expected 5 to be 4 // Object.is equality" at: "/root-directory/__tests__/test-file-1.test.ts:20:28" actual: "5" expected: "4" ... ok 2 - __tests__/test-file-1.test.ts > first test file > 4 - 2 should equal 2 # time=0.00ms ``` -------------------------------- ### Running Type Checks with Different Package Managers Source: https://vitest.dev/guide/testing-types Examples of how to run Vitest with type checking enabled using npm, yarn, pnpm, and bun. ```bash npm run test ``` ```bash yarn test ``` ```bash pnpm run test ``` ```bash bun test ``` -------------------------------- ### Dot Reporter Example Output Source: https://vitest.dev/guide/reporters Example terminal output for a passing test suite using the dot reporter. It shows a series of dots representing completed tests, followed by a summary. ```bash .... Test Files 2 passed (2) Tests 4 passed (4) Start at 12:34:32 Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms) ``` -------------------------------- ### Install OpenTelemetry dependencies Source: https://vitest.dev/guide/open-telemetry Required packages for enabling OpenTelemetry tracing in a Node.js environment. ```shell npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto ``` -------------------------------- ### Vitest test execution output Source: https://vitest.dev/guide Example output shown in the terminal after running Vitest tests. ```txt ✓ sum.test.js (1) ✓ adds 1 + 2 to equal 3 Test Files 1 passed (1) Tests 1 passed (1) Start at 02:15:44 Duration 311ms ``` -------------------------------- ### Configure Browser OpenTelemetry Source: https://vitest.dev/guide/open-telemetry Setup the browser-compatible SDK and update the Vitest configuration to include the browser SDK path. ```js import { BatchSpanProcessor, WebTracerProvider, } from '@opentelemetry/sdk-trace-web' import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto' const provider = new WebTracerProvider({ spanProcessors: [ new BatchSpanProcessor(new OTLPTraceExporter()), ], }) provider.register() export default provider ``` ```js import { defineConfig } from 'vitest/config' export default defineConfig({ test: { browser: { enabled: true, provider: 'playwright', instances: [{ browser: 'chromium' }], }, experimental: { openTelemetry: { enabled: true, sdkPath: './otel.js', browserSdkPath: './otel-browser.js', }, }, }, }) ``` -------------------------------- ### Cleanup with `beforeEach` Return Value Source: https://vitest.dev/guide/learn/setup-teardown Register a cleanup function by returning it from `beforeEach`. This is useful when setup and teardown are closely related. ```js import { beforeEach } from 'vitest' beforeEach(() => { const server = startServer() return () => { server.close() } }) ``` -------------------------------- ### GitHub Actions Example for Vitest Sharding Source: https://vitest.dev/guide/improving-performance This YAML configuration demonstrates how to set up GitHub Actions to run Vitest tests in parallel using sharding and merge the reports. ```yaml # Inspired from https://playwright.dev/docs/test-sharding name: Tests on: push: branches: - main jobs: tests: runs-on: ubuntu-latest strategy: matrix: shardIndex: [1, 2, 3, 4] shardTotal: [4] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - name: Install pnpm uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 - name: Install dependencies run: pnpm i - name: Run tests run: pnpm run test --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - name: Upload blob report to GitHub Actions Artifacts if: ${{ !cancelled() }} uses: actions/upload-artifact@v4 with: name: blob-report-${{ matrix.shardIndex }} path: .vitest-reports/* include-hidden-files: true retention-days: 1 - name: Upload attachments to GitHub Actions Artifacts if: ${{ !cancelled() }} uses: actions/upload-artifact@v4 with: name: blob-attachments-${{ matrix.shardIndex }} path: .vitest-attachments/** include-hidden-files: true retention-days: 1 merge-reports: if: ${{ !cancelled() }} needs: [tests] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - name: Install pnpm uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 - name: Install dependencies run: pnpm i - name: Download blob reports from GitHub Actions Artifacts uses: actions/download-artifact@v4 with: path: .vitest-reports pattern: blob-report-* merge-multiple: true - name: Download attachments from GitHub Actions Artifacts uses: actions/download-artifact@v4 with: path: .vitest-attachments pattern: blob-attachments-* merge-multiple: true - name: Merge reports run: npx vitest --merge-reports ``` -------------------------------- ### Basic Form Accessibility Snapshot Source: https://vitest.dev/guide/browser/aria-snapshots Example HTML structure for a login form used in snapshot testing. ```html
``` -------------------------------- ### Standalone Mode CLI Execution Source: https://vitest.dev/guide/migration Execute Vitest in standalone mode using npm scripts. This example shows how to start Vitest without running files and then run a specific test file. ```bash # Start Vitest in standalone mode, without running any files on start $ pnpm run test:dev # Run math.test.ts immediately $ pnpm run test:dev math.test.ts ``` -------------------------------- ### One-Time Setup/Teardown for a File Source: https://vitest.dev/guide/learn/setup-teardown Employ `beforeAll` and `afterAll` for expensive operations that only need to run once per file, such as database connections or server startups. ```javascript import { afterAll, beforeAll, expect, test } from 'vitest' let db beforeAll(async () => { db = await connectToDatabase() }) afterAll(async () => { await db.close() }) test('can query users', async () => { const users = await db.query('SELECT * FROM users') expect(users.length).toBeGreaterThan(0) }) test('can query products', async () => { const products = await db.query('SELECT * FROM products') expect(products.length).toBeGreaterThan(0) }) ``` -------------------------------- ### View reference screenshot error message Source: https://vitest.dev/guide/browser/visual-regression-testing Example of the console output when a new reference screenshot is generated for the first time. ```text expect(element).toMatchScreenshot() No existing reference screenshot found; a new one was created. Review it before running tests again. Reference screenshot: tests/__screenshots__/hero.test.ts/hero-section-chromium-darwin.png ``` -------------------------------- ### Vitest Module Transformation Example Source: https://vitest.dev/guide/mocking/modules Illustrates how Vitest transforms static imports into dynamic ones and moves `vi.mock` calls to the top to ensure mocks are registered before imports. ```typescript import { answer } from './answer.js' vi.mock('./answer.js') console.log(answer) ``` ```typescript vi.mock('./answer.js') const __vitest_module_0__ = await __handle_mock__( () => import('./answer.js') ) // to keep the live binding, we have to access // the export on the module namespace console.log(__vitest_module_0__.answer()) ``` -------------------------------- ### Update Visual Regression Screenshots Workflow Source: https://vitest.dev/guide/browser/visual-regression-testing This YAML workflow is triggered manually and handles the update of visual regression screenshots. It includes steps for checkout, Git configuration, dependency installation, Playwright browser setup, running the update command, checking for changes, committing, and pushing updates. It also generates a summary for the GitHub Actions run. ```yaml name: Update Visual Regression Screenshots on: workflow_dispatch: # manual trigger only env: AUTHOR_NAME: 'github-actions[bot]' AUTHOR_EMAIL: '41898282+github-actions[bot]@users.noreply.github.com' COMMIT_MESSAGE: | test: update visual regression screenshots Co-authored-by: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com> jobs: update-screenshots: runs-on: ubuntu-24.04 # safety first: don't run on main if: github.ref_name != github.event.repository.default_branch # one at a time per branch concurrency: group: visual-regression-screenshots@${{ github.ref_name }} cancel-in-progress: true permissions: contents: write # needs to push changes steps: - name: Checkout selected branch uses: actions/checkout@v4 with: ref: ${{ github.ref_name }} # use PAT if triggering other workflows # token: ${{ secrets.GITHUB_TOKEN }} - name: Configure Git run: | git config --global user.name "${{ env.AUTHOR_NAME }}" git config --global user.email "${{ env.AUTHOR_EMAIL }}" # your setup steps here (node, pnpm, whatever) - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 24 - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx --no playwright install --with-deps --only-shell # the magic happens below đŸĒ„ - name: Update Visual Regression Screenshots run: npm run test:visual --update # check what changed - name: Check for changes id: check_changes run: | CHANGED_FILES=$(git status --porcelain | awk '{print $2}') if [ "${CHANGED_FILES:+x}" ]; then echo "changes=true" >> $GITHUB_OUTPUT echo "Changes detected" # save the list for the summary echo "changed_files<> $GITHUB_OUTPUT echo "$CHANGED_FILES" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT echo "changed_count=$(echo "$CHANGED_FILES" | wc -l)" >> $GITHUB_OUTPUT else echo "changes=false" >> $GITHUB_OUTPUT echo "No changes detected" fi # commit if there are changes - name: Commit changes if: steps.check_changes.outputs.changes == 'true' run: | git add -A git commit -m "${{ env.COMMIT_MESSAGE }}" - name: Push changes if: steps.check_changes.outputs.changes == 'true' run: git push origin ${{ github.ref_name }} # pretty summary for humans - name: Summary run: | if [[ "${{ steps.check_changes.outputs.changes }}" == "true" ]]; then echo "### 📸 Visual Regression Screenshots Updated" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Successfully updated **${{ steps.check_changes.outputs.changed_count }}** screenshot(s) on ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "#### Changed Files:" >> $GITHUB_STEP_SUMMARY echo "```" >> $GITHUB_STEP_SUMMARY echo "${{ steps.check_changes.outputs.changed_files }}" >> $GITHUB_STEP_SUMMARY echo "```" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "✅ The updated screenshots have been committed and pushed. Your visual regression baseline is now up to date!" >> $GITHUB_STEP_SUMMARY else echo "### â„šī¸ No Screenshot Updates Required" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "The visual regression test command ran successfully but no screenshots needed updating." >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "All screenshots are already up to date! 🎉" >> $GITHUB_STEP_SUMMARY fi ``` -------------------------------- ### Lit Component Rendering with Vitest Browser Mode Source: https://vitest.dev/guide/browser Demonstrates rendering Lit components using `vitest-browser-lit`. This snippet shows the import and setup for rendering Lit elements. ```ts import { render } from 'vitest-browser-lit' import { html } from 'lit' import './greeter-button' ``` -------------------------------- ### Initialize Vitest browser configuration Source: https://vitest.dev/guide/cli Use `vitest init browser` to set up project configuration specifically for browser testing. ```bash vitest init browser ``` -------------------------------- ### Weak Assertion Example Source: https://vitest.dev/guide/learn/writing-tests-with-ai An example of a test that provides false confidence by only checking if a value is defined. ```js test('creates a user', () => { const user = createUser('Alice', 'alice@example.com') expect(user).toBeDefined() // this passes for almost anything }) ``` -------------------------------- ### Define Suite-Level Hooks with Fixtures Source: https://vitest.dev/guide/test-context Illustrates using suite-level hooks like aroundAll and beforeAll with file-scoped fixtures. ```ts const test = baseTest .extend('config', { scope: 'file' }, () => loadConfig()) .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => { const db = await createDatabase(config) onCleanup(() => db.close()) return db }) // Access file-scoped fixtures in suite-level hooks test.aroundAll(async (runSuite, { database }) => { await database.transaction(runSuite) }) test.beforeAll(async ({ database }) => { await database.createUsers() }) test.afterAll(async ({ database }) => { await database.removeUsers() }) ``` -------------------------------- ### Install Playwright Browsers in CI Source: https://vitest.dev/guide/browser/visual-regression-testing This YAML snippet shows how to install Playwright browsers and dependencies within a GitHub Actions workflow before running visual regression tests. ```yaml # ...the rest of the workflow - name: Install Playwright Browsers run: npx --no playwright install --with-deps --only-shell ``` -------------------------------- ### Vitest Configuration with Default and Custom Project Names Source: https://vitest.dev/guide/browser/multiple-setups Illustrates how Vitest assigns project names. In the 'default' config, 'chromium' gets 'chromium' and 'firefox' gets 'custom'. In the 'custom' config, 'chromium' becomes 'custom (chromium)' and 'firefox' becomes 'manual'. ```typescript export default defineConfig({ test: { browser: { instances: [ // name: chromium { browser: 'chromium' }, // name: custom { browser: 'firefox', name: 'custom' } ] } } }) ``` ```typescript export default defineConfig({ test: { name: 'custom', browser: { instances: [ // name: custom (chromium) { browser: 'chromium' }, // name: manual { browser: 'firefox', name: 'manual' }, ] } } }) ``` -------------------------------- ### Example JavaScript function Source: https://vitest.dev/guide A simple JavaScript function to be tested. ```js export function sum(a, b) { return a + b } ``` -------------------------------- ### createVitest Source: https://vitest.dev/guide/advanced Creates a Vitest instance without starting the test execution. ```APIDOC ## createVitest ### Description Creates a Vitest instance without starting tests or validating installed packages. ### Parameters - **mode** (VitestRunMode) - Required - The run mode. - **options** (CliOptions) - Required - Configuration options. - **viteOverrides** (ViteUserConfig) - Optional - Vite configuration overrides. - **vitestOptions** (VitestOptions) - Optional - Vitest specific options. ### Request Example ```js import { createVitest } from 'vitest/node' const vitest = await createVitest('test', { watch: false }) ``` ``` -------------------------------- ### Basic Snapshot Test Source: https://vitest.dev/guide/learn/snapshots This snippet demonstrates how to create a basic snapshot test using `toMatchSnapshot()`. The first time it runs, Vitest creates a snapshot file in the `__snapshots__` directory. Subsequent runs compare the output against this file. ```javascript import { expect, test } from 'vitest' function generateGreeting(name) { return { message: `Hello, ${name}!`, timestamp: null, version: 2, } } test('generates a greeting', () => { expect(generateGreeting('Alice')).toMatchSnapshot() }) ``` -------------------------------- ### Default reporter output example Source: https://vitest.dev/guide/test-annotations The default reporter displays annotations only when a test fails. ```text ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ FAIL example.test.js > an example of a test with annotation Error: thrown error ❯ example.test.js:11:21 9 | await annotate('annotation 1') 10| await annotate('annotation 2', 'warning') 11| throw new Error('thrown error') | ^ 12| }) ❯ example.test.js:9:15 notice â†ŗ annotation 1 ❯ example.test.js:10:15 warning â†ŗ annotation 2 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ ``` -------------------------------- ### Strong Assertion Example Source: https://vitest.dev/guide/learn/writing-tests-with-ai A more robust test that validates specific object properties and types. ```js test('creates a user with the correct fields', () => { const user = createUser('Alice', 'alice@example.com') expect(user).toMatchObject({ name: 'Alice', email: 'alice@example.com', }) expect(user.id).toBeTypeOf('string') }) ``` -------------------------------- ### Use TAP Reporter via CLI Source: https://vitest.dev/guide/reporters Run Vitest with the TAP reporter directly from the command line. ```bash npx vitest --reporter=tap ``` -------------------------------- ### Define a sample Dog class Source: https://vitest.dev/guide/mocking/classes A standard class definition used as a target for mocking examples. ```ts class Dog { name: string constructor(name: string) { this.name = name } static getType(): string { return 'animal' } greet = (): string => { return `Hi! My name is ${this.name}!` } speak(): string { return 'bark!' } isHungry() {} feed() {} } ``` -------------------------------- ### Enable Tracing via CLI Source: https://vitest.dev/guide/browser/trace-view Alternatively, enable Playwright tracing directly from the command line using the --browser.trace=on flag. ```bash vitest --browser.trace=on ``` -------------------------------- ### Select Reporter via CLI Source: https://vitest.dev/guide/reporters Use the `--reporter` option in the command line to specify the desired reporter. ```bash npx vitest --reporter=verbose ``` -------------------------------- ### Verbose reporter output example Source: https://vitest.dev/guide/test-annotations The verbose reporter displays annotations regardless of test success or failure. ```text ✓ example.test.js > an example of a test with annotation ❯ example.test.js:9:15 notice â†ŗ annotation 1 ❯ example.test.js:10:15 warning â†ŗ annotation 2 ``` -------------------------------- ### Spying and Mocking Functions with Vitest Source: https://vitest.dev/guide/mocking/functions Demonstrates tracking method calls with vi.spyOn and using vi.fn to create a mock callback function. ```javascript import { afterEach, describe, expect, it, vi } from 'vitest' const messages = { items: [ { message: 'Simple test message', from: 'Testman' }, // ... ], addItem(item) { messages.items.push(item) messages.callbacks.forEach(callback => callback(item)) }, onItem(callback) { messages.callbacks.push(callback) }, getLatest, // can also be a `getter or setter if supported` } function getLatest(index = messages.items.length - 1) { return messages.items[index] } it('should get the latest message with a spy', () => { const spy = vi.spyOn(messages, 'getLatest') expect(spy.getMockName()).toEqual('getLatest') expect(messages.getLatest()).toEqual( messages.items[messages.items.length - 1], ) expect(spy).toHaveBeenCalledTimes(1) spy.mockImplementationOnce(() => 'access-restricted') expect(messages.getLatest()).toEqual('access-restricted') expect(spy).toHaveBeenCalledTimes(2) }) it('passing down the mock', () => { const callback = vi.fn() messages.onItem(callback) messages.addItem({ message: 'Another test message', from: 'Testman' }) expect(callback).toHaveBeenCalledWith({ message: 'Another test message', from: 'Testman', }) }) ``` -------------------------------- ### Preview HTML Report Source: https://vitest.dev/guide/ui Use the vite preview command to serve the generated HTML report. The `--outDir` option specifies the directory containing the report, which defaults to './html'. ```sh npx vite preview --outDir ./html ``` -------------------------------- ### Configure memfs mocks Source: https://vitest.dev/guide/mocking/file-system Create these files in the project root to automatically redirect fs calls to memfs. ```ts // we can also use `import`, but then // every export should be explicitly defined const { fs } = require('memfs') module.exports = fs ``` ```ts // we can also use `import`, but then // every export should be explicitly defined const { fs } = require('memfs') module.exports = fs.promises ``` -------------------------------- ### Configure unbuild for Production Build Source: https://vitest.dev/guide/in-source Configure unbuild's `replace` option to substitute `import.meta.vitest` with `undefined` for production builds, ensuring dead code elimination. ```javascript import { defineBuildConfig } from 'unbuild' export default defineBuildConfig({ replace: { // [!code ++] 'import.meta.vitest': 'undefined', // [!code ++] }, // [!code ++] // other options }) ``` -------------------------------- ### Create spies and mocks using Vitest utilities Source: https://vitest.dev/guide/migration Replace Sinon's spy, stub, and mock creation with Vitest's vi utilities. ```ts // Sinon const sinon = require('sinon') const spy = sinon.spy() const stub = sinon.stub(obj, 'method') const mock = sinon.mock(obj) // Vitest import { vi } from 'vitest' const spy = vi.fn() const stub = vi.spyOn(obj, 'method') // Vitest doesn't have "mocks" - use spies instead ``` -------------------------------- ### Configure Vue Snapshot Serializer Source: https://vitest.dev/guide/migration To use Vue snapshots with Vitest, install `jest-serializer-vue` and specify it in the `snapshotSerializers` configuration. ```javascript import { defineConfig } from 'vitest/config' export default defineConfig({ test: { snapshotSerializers: ['jest-serializer-vue'] } }) ```