# Agent Skill: toldo-tdd-vitest ## Metadata ```yaml name: toldo-tdd-vitest description: Workflow TDD con Vitest para Vite+Capacitor. Mock de plugins, fake-indexeddb, Testing Library. Ciclo Red-Green-Refactor estricto. ``` ## When to use Use this skill when: - Writing tests - Implementing features with TDD - Setting up test infrastructure - Mocking dependencies (Capacitor plugins, Dexie) - Testing components ## TDD Workflow (Red-Green-Refactor) ### For Domain/Core (MANDATORY TDD) 1. **RED**: Write a failing test that describes the behavior 2. **GREEN**: Write minimal code to make the test pass 3. **REFACTOR**: Improve code while keeping tests green 4. **REPEAT**: Next test case ### For Data/Services Write tests, can use mocks/fake DB. Still prefer test-first when possible. ### For UI Test behavior and user interactions, not implementation details. ## Setup ### Dependencies ```json { "devDependencies": { "vitest": "^1.0.0", "jsdom": "^23.0.0", "@testing-library/vue": "^8.0.0", // or @testing-library/react/svelte "@testing-library/user-event": "^14.0.0", "fake-indexeddb": "^5.0.0" } } ``` ### vitest.config.ts ```typescript import { defineConfig } from 'vitest/config'; import path from 'path'; export default defineConfig({ test: { globals: true, environment: 'jsdom', setupFiles: ['./tests/setup.ts'], }, resolve: { alias: { '@core': path.resolve(__dirname, '../../packages/core/src'), '@data': path.resolve(__dirname, '../../packages/data/src'), '@services': path.resolve(__dirname, '../../packages/services/src'), '@ui': path.resolve(__dirname, '../../packages/ui/src'), }, }, }); ``` ### tests/setup.ts ```typescript import 'fake-indexeddb/auto'; ``` ## Mocking Capacitor Plugins **NEVER** test against real Capacitor plugins. Always mock. ```typescript import { vi } from 'vitest'; vi.mock('@capacitor/core', () => ({ Capacitor: { isNativePlatform: () => false, getPlatform: () => 'web', }, })); vi.mock('@capacitor/filesystem', () => ({ Filesystem: { writeFile: vi.fn(), readFile: vi.fn(), }, })); ``` ## Testing with Dexie (fake-indexeddb) ```typescript import { describe, it, expect, beforeEach } from 'vitest'; import { db } from '../db'; describe('ProductorRepository', () => { beforeEach(async () => { await db.delete(); await db.open(); }); it('should create productor', async () => { // test... }); }); ``` ## Testing UI Components Use @testing-library best practices: - Query by role, label, text (accessible queries) - Use userEvent for interactions - Test behavior, not implementation - Avoid testing internal state ```typescript import { render, screen } from '@testing-library/vue'; import userEvent from '@testing-library/user-event'; import Button from './Button.vue'; it('calls onClick when clicked', async () => { const user = userEvent.setup(); const onClick = vi.fn(); render(Button, { props: { onClick } }); await user.click(screen.getByRole('button')); expect(onClick).toHaveBeenCalled(); }); ``` ## Commands ```bash # Run tests in watch mode (TDD) npm test -- --watch # Run all tests npm test # Run with coverage npm test -- --coverage # Run specific file npm test path/to/file.test.ts ``` ## Rules - **Core tests**: Pure unit tests, no mocks needed, fast - **Data tests**: Use fake-indexeddb, test in isolation - **Services tests**: Mock repositories - **UI tests**: Use Testing Library, mock services/composables - **Capacitor**: Always mock in unit/integration tests - **No tests in APK/emulator for initial development** - web tests are sufficient - **Keep tests fast** - if slow, something is wrong - **One assertion concept per test** when possible ## TDD Checklist - [ ] Test written before implementation (for core) - [ ] Test fails initially (RED) - [ ] Minimal implementation makes it pass (GREEN) - [ ] Code refactored (REFACTOR) - [ ] All tests still pass - [ ] Test is meaningful and tests behavior ## Resources - [Vitest Docs](https://vitest.dev/) - [Testing Library](https://testing-library.com/) - [fake-indexeddb](https://github.com/dumbmatter/fakeIndexedDB) - Follow Red-Green-Refactor strictly for domain logic