4.1 KiB
4.1 KiB
Agent Skill: toldo-tdd-vitest
Metadata
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)
- RED: Write a failing test that describes the behavior
- GREEN: Write minimal code to make the test pass
- REFACTOR: Improve code while keeping tests green
- 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
{
"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
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
import 'fake-indexeddb/auto';
Mocking Capacitor Plugins
NEVER test against real Capacitor plugins. Always mock.
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)
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
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
# 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
- Testing Library
- fake-indexeddb
- Follow Red-Green-Refactor strictly for domain logic