Vitestテスト設計と品質基準を適用。カバレッジ要件とモック使用ガイドを提供。ユニットテスト作成時に使用。
import { describe, it, expect, beforeEach, vi } from 'vitest'vi.mock() を使用必須: 単体テストのカバレッジは70%以上 指標: Statements(文)、Branches(分岐)、Functions(関数)、Lines(行)
単体テスト(Unit Tests)
統合テスト(Integration Tests)
E2Eテストでの機能横断検証
src/
└── application/
└── services/
├── __tests__/
│ ├── service.test.ts # 単体テスト
│ └── service.int.test.ts # 統合テスト
└── service.ts
{対象ファイル名}.test.ts{対象ファイル名}.int.test.ts推奨: すべてのテストを常に有効に保つ
避けるべき: test.skip()やコメントアウト
正常系に加え、境界値と異常系を含める。
it('returns 0 for empty array', () => expect(calc([])).toBe(0))
it('throws on negative price', () => expect(() => calc([{price: -1}])).toThrow())
期待値はリテラルで記述。実装ロジックを再現しない。 有効なテスト: 期待値 ≠ モック戻り値(実装による変換・処理がある)
expect(calcTax(100)).toBe(10) // not: 100 * TAX_RATE
呼び出し順序・回数ではなく結果を検証。
expect(mock).toHaveBeenCalledWith('a') // not: toHaveBeenNthCalledWith
各テストに最低1つの検証を含める。
it('creates user', async () => {
const user = await createUser({name: 'test'})
expect(user.id).toBeDefined()
})
直接依存の外部I/Oのみモック。間接依存は実物使用。
vi.mock('./database') // 外部I/Oのみ
不変条件やプロパティを検証する場合はfast-checkを使用。
import fc from 'fast-check'
it('reverses twice equals original', () => {
fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
return JSON.stringify(arr.reverse().reverse()) === JSON.stringify(arr)
}))
})
使用条件: Design DocのACにProperty注釈が付与されている場合に使用。
// 必要な部分のみ
type TestRepo = Pick<Repository, 'find' | 'save'>
const mock: TestRepo = { find: vi.fn(), save: vi.fn() }
// やむを得ない場合のみ、理由明記
const sdkMock = {
call: vi.fn()
} as unknown as ExternalSDK // 外部SDKの複雑な型のため
モックは呼び出しパターンを検証するが、データ層の正確性は検証できない。モックのみのテストでは以下が検出されずに通過する:
実データベースエンジンに対するデータ層の正確性を検証するオプション:
適切なアプローチはプロジェクト環境とCI/CD構成に依存する。
import { describe, it, expect, vi } from 'vitest'
vi.mock('./userService', () => ({
getUserById: vi.fn(),
updateUser: vi.fn()
}))
describe('ComponentName', () => {
it('should follow AAA pattern', () => {
const input = 'test'
const result = someFunction(input)
expect(result).toBe('expected')
})
})