Skip to main content

unit-testing

Guides writing and maintaining Vitest unit tests for the bootc extension's backend, frontend, and shared packages. Covers mocking @podman-desktop/api, RPC clients, Svelte stores, and Node.js modules. Triggers when creating or modifying .spec.ts files, fixing Vitest failures, or adding test coverage.

Quellinformationen

Repository
podman-desktop/extension-bootc
Letzte Quellaktivität
15. Mai 2026 um 17:31
Erkannte Sprache von SKILL.md
Englisch
Sterne
472
Forks
33

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
unit-testing
description
Guides writing and maintaining Vitest unit tests for the bootc extension's backend, frontend, and shared packages. Covers mocking @podman-desktop/api, RPC clients, Svelte stores, and Node.js modules. Triggers when creating or modifying .spec.ts files, fixing Vitest failures, or adding test coverage.
paths
["packages/backend/src/**/*.spec.ts","packages/frontend/src/**/*.spec.ts","packages/shared/src/**/*.spec.ts"]
argument-hint
[test-file-or-pattern]
# Unit Testing for Bootc Extension ## Framework - **Vitest 4** with v8 coverage provider - **Backend**: Node.js environment, mocked `@podman-desktop/api` - **Frontend**: JSDOM environment, `@testing-library/svelte` for components - **Shared**: Node.js environment for message proxy and model tests ## Running Tests ```bash pnpm test # all packages pnpm test:backend # packages/backend with coverage pnpm test:frontend # packages/frontend with coverage pnpm test:shared # packages/shared with coverage # Single file npx vitest run packages/backend/src/build-disk-image.spec.ts # Watch mode npx vitest watch packages/backend/src/ ``` ## Backend Test Patterns ### Mocking @podman-desktop/api The backend's `vite.config.js` aliases `@podman-desktop/api` to a mock file. Mock only the namespaces your test actually uses: ```typescript import { vi, test, expect, beforeEach, describe } from 'vitest'; import * as extensionApi from '@podman-desktop/api'; vi.mock('@podman-desktop/api', async () => ({ // Mock only what your test needs — check existing tests for patterns: // grep -l "vi.mock('@podman-desktop/api'" packages/backend/src/*.spec.ts })); ``` To see the full mock shape used in existing tests: ```bash grep -A 30 "vi.mock('@podman-desktop/api'" packages/backend/src/*.spec.ts | head -60 ``` ### Testing Backend Functions ```typescript import { describe, test, expect, vi, beforeEach } from 'vitest'; import { buildDiskImage } from './build-disk-image'; vi.mock('@podman-desktop/api'); vi.mock('./container-utils'); vi.mock('./history'); beforeEach(() => { vi.clearAllMocks(); }); describe('buildDiskImage', () => { test('should create build container with correct volumes', async () => { // Arrange const buildInfo = { id: 'test-id', image: 'quay.io/test/image', tag: 'latest', type: ['qcow2'] as BuildType[], folder: '/output', // ... }; // Act await buildDiskImage(buildInfo); // Assert expect(containerEngine.createContainer).toHaveBeenCalledWith( expect.anything(), expect.objectContaining({ Image: expect.stringContaining('bootc-image-builder'), }), ); }); }); ``` ### Mocking Node.js Modules ```typescript import { vi } from 'vitest'; vi.mock('node:fs', async () => ({ promises: { mkdir: vi.fn(), readFile: vi.fn(), writeFile: vi.fn(), }, existsSync: vi.fn(), })); vi.mock('node:child_process', async () => ({ exec: vi.fn(), })); ``` ## Frontend Test Patterns ### Component Testing with @testing-library/svelte ```typescript import { vi, test, expect, beforeEach } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/svelte'; import '@testing-library/jest-dom/vitest'; import MyComponent from './MyComponent.svelte'; // Mock the RPC client vi.mock('/@/api/client', async () => ({ bootcClient: { listBootcImages: vi.fn().mockResolvedValue([]), buildImage: vi.fn(), }, rpcBrowser: { subscribe: vi.fn().mockReturnValue({ unsubscribe: vi.fn() }), }, })); test('renders heading', async () => { render(MyComponent, { props: { imageName: 'test' } }); expect(screen.getByText('Build Disk Image')).toBeInTheDocument(); }); test('clicking build button triggers build', async () => { render(MyComponent); const buildButton = screen.getByRole('button', { name: 'Build' }); await fireEvent.click(buildButton); expect(bootcClient.buildImage).toHaveBeenCalled(); }); ``` ### Mocking Svelte Stores ```typescript import { vi } from 'vitest'; import { readable } from 'svelte/store'; vi.mock('/@/stores/imageInfo', async () => ({ imageInfos: readable([{ Id: 'abc123', RepoTags: ['quay.io/test:latest'], Labels: { 'containers.bootc': '' } }]), })); ``` ### Path Aliases in Tests Frontend tests resolve `/@/` to `packages/frontend/src/` and `/@shared/` to `packages/shared/` via Vite config. Use these aliases in mocks: ```typescript vi.mock('/@/api/client'); // → packages/frontend/src/api/client vi.mock('/@shared/src/models/bootc'); // → packages/shared/src/models/bootc ``` ## Shared Package Tests ### MessageProxy Tests ```typescript import { test, expect, vi } from 'vitest'; import { RpcBrowser, RpcExtension } from './MessageProxy'; test('RPC call resolves with result', async () => { // Test the RPC proxy mechanism }); ``` ## Test File Naming - Test files: `*.spec.ts` colocated with source files - Example: `build-disk-image.ts` → `build-disk-image.spec.ts` ## Coverage Coverage reports are generated in `lcov` and `text` format: ```bash pnpm test:backend # generates packages/backend/coverage/ pnpm test:frontend # generates packages/frontend/coverage/ ``` ## Common Issues ### "Cannot find module @podman-desktop/api" The mock alias is configured in `packages/backend/vite.config.js`. If you see this error, ensure the test file is being run from the correct package. ### "Not a Svelte component" The test environment needs the Svelte vite plugin. Frontend tests use the config from `packages/frontend/vite.config.js` which includes `@sveltejs/vite-plugin-svelte`. ### Test Retries Frontend tests retry failed tests 2x (configured in `packages/frontend/vite.config.js`). Backend tests do not retry.
Auf GitHub ansehen