# Test Kernels URL: /docs/guides/testing-kernels Test Kernels [#test-kernels] Use the `@taucad/runtime/testing` utilities to write unit tests for custom kernels and middleware. The package provides worker setup, mock runtimes, filesystem seeding, and geometry validation helpers. Prerequisites [#prerequisites] * [Install @taucad/runtime](../getting-started/installation) * Completed the [Quick Start](../getting-started/quick-start) * Vitest configured in your project (peer dependency of `@taucad/runtime`) Goal [#goal] Write unit tests that exercise kernel logic, middleware hooks, and geometry output using `createTestWorker`, mock runtimes, and geometry validation helpers. Steps [#steps] 1. Import Testing Utilities from @taucad/runtime/testing [#1-import-testing-utilities-from-taucadruntimetesting] All testing helpers are exported from the testing subpath: ```typescript import { createTestWorker, initializeWorkerForTesting, seedTestFileSystem, clearTestFileSystem, createMockLogger, createMockFileSystem, createMockRuntime, createMockRuntimeClient, createMockDependencies, createMockCreateGeometryHandler, createMockGetParametersHandler, createSuccessResult, createErrorResult, createMockInput, createMockResponse, MockKernelWorker, validateGlbData, getInspectReport, createGeometryTestHelpers, } from '@taucad/runtime/testing'; ``` 2. Use createTestWorker for Kernel Integration Tests [#2-use-createtestworker-for-kernel-integration-tests] `createTestWorker` creates and initializes a [`KernelRuntimeWorker`](../concepts/worker-model) with a kernel definition and seeded files. It uses the production code path: ```typescript import { describe, it, expect } from 'vitest'; import { createTestWorker } from '@taucad/runtime/testing'; import replicadDefinition from '@taucad/runtime/kernels/replicad'; describe('Replicad kernel', () => { it('creates geometry from TypeScript', async () => { const worker = await createTestWorker(replicadDefinition, { 'main.ts': ` import { drawRoundedRectangle } from 'replicad'; export default function main() { return drawRoundedRectangle(30, 50, 5).sketchOnPlane('XY').extrude(10); } `, }); const result = await worker.createGeometry({ file: { filename: 'main.ts', path: '/projects/test' }, parameters: {}, }); expect(result.success).toBe(true); if (result.success) { expect(result.data).toHaveLength(1); } }); }); ``` 3. Use initializeWorkerForTesting for Custom Worker Setup [#3-use-initializeworkerfortesting-for-custom-worker-setup] When you need more control over worker initialization (e.g., custom middleware, telemetry): ```typescript @ts-nocheck import { KernelRuntimeWorker } from '@taucad/runtime/worker'; import { initializeWorkerForTesting, seedTestFileSystem } from '@taucad/runtime/testing'; await seedTestFileSystem({ '/projects/test/main.ts': `export default function main() { return null; }`, }); const worker = new KernelRuntimeWorker(); await initializeWorkerForTesting(worker, { onLog: ({ message }) => console.log(message), workerOptions: { kernelModules: [ /* ... */ ], }, }); ``` 4. Seed and Clear the Test Filesystem [#4-seed-and-clear-the-test-filesystem] `seedTestFileSystem` resets the in-memory filesystem and writes files. `clearTestFileSystem` resets without seeding: ```typescript @ts-nocheck import { seedTestFileSystem, clearTestFileSystem } from '@taucad/runtime/testing'; beforeEach(async () => { await seedTestFileSystem({ '/projects/test/main.ts': 'export default function main() { return null; }', '/projects/test/lib/utils.ts': 'export const x = 1;', }); }); afterEach(async () => { await clearTestFileSystem(); }); ``` 5. Use Mock Utilities for Middleware Tests [#5-use-mock-utilities-for-middleware-tests] For middleware unit tests, use mocks to avoid a real worker: ```typescript @ts-nocheck import { createMockLogger, createMockFileSystem, createMockRuntime, createMockInput, createMockCreateGeometryHandler, createSuccessResult, createErrorResult, } from '@taucad/runtime/testing'; const logger = createMockLogger(); const filesystem = createMockFileSystem({ existsResult: true, readFileResult: (path) => Promise.resolve(new TextEncoder().encode('content')), }); const runtime = createMockRuntime({ filesystemOverrides: { existsResult: true }, dependencies: [], dependencyHash: 'abc123', }); const input = createMockInput({ filePath: '/projects/test/main.ts' }); const handler = createMockCreateGeometryHandler(createSuccessResult([])); const result = await myMiddleware.wrapCreateGeometry(input, handler, runtime); expect(result.success).toBe(true); ``` **`createMockRuntimeClient()`** -- Returns a [`RuntimeClient`](../api/client) mock for transport-level testing. **`MockKernelWorker`** -- A worker-shaped mock class for middleware integration tests. **`createMockResponse(body, headers?)`** -- Creates a mock `Response` object for testing HTTP-dependent kernels (e.g., Zoo). 6. Validate Geometry with validateGlbData and getInspectReport [#6-validate-geometry-with-validateglbdata-and-getinspectreport] Use `validateGlbData` to assert GLB format and `getInspectReport` for detailed geometry stats: ```typescript @ts-nocheck import { validateGlbData, getInspectReport, extractGltfFromResult, getGeometryStatsFromInspect, getBoundingBoxFromInspect, } from '@taucad/runtime/testing'; const result = await worker.createGeometry({ /* ... */ }); const glb = extractGltfFromResult(result); expect(glb).toBeDefined(); validateGlbData(glb!); const report = await getInspectReport(glb!); const stats = getGeometryStatsFromInspect(report); console.log(`Vertices: ${stats.vertexCount}, Faces: ${stats.faceCount}, Meshes: ${stats.meshCount}`); const bbox = getBoundingBoxFromInspect(report); if (bbox) { console.log(`Size: ${bbox.size}, Center: ${bbox.center}`); } ``` 7. Use createGeometryTestHelpers for Geometry Assertions [#7-use-creategeometrytesthelpers-for-geometry-assertions] `createGeometryTestHelpers` provides helpers for common geometry assertions: ```typescript @ts-nocheck import { createGeometryTestHelpers, createGeometryVariant } from '@taucad/runtime/testing'; const helpers = createGeometryTestHelpers(); const result = await worker.createGeometry({ /* ... */ }); await helpers.expectValidGltf(result); await helpers.expectMeshCount(result, 1); await helpers.expectVertexCount(result, 24); await helpers.expectBoundingBoxSize(result, [30, 50, 10], 0.1); ``` **`createGeometryVariant(base, overrides)`** -- Create variant `GeometryExpectation` objects from a base for parametric testing. Variations [#variations] * **`createSuccessResult` / `createErrorResult`**: Build `CreateGeometryResult` values for middleware tests without running a kernel. * **`createMockDependencies(overrides?)`**: Create mock `Dependency[]` arrays for dependency hash testing. * **`createMockGetParametersHandler(result?)`**: Create a mock handler for `wrapGetParameters` tests. * **Skip bundler in tests**: Use `skipBundler: true` in `createTestWorker` for kernels that do not need bundling. Related [#related] * [Create a Custom Kernel](./custom-kernel) -- Test custom kernel definitions * [Create Custom Middleware](./custom-middleware) -- Test middleware with createMockRuntime * [API Reference: Testing](../api/testing) -- Full testing utility documentation