vitest
VitestはViteネイティブの高速パフォーマンス、ESMサポート、TypeScriptファーストな設計を備えたモダンなTypeScriptテストフレームワークです。TypeScriptプロジェクトのユニットテストや統合テストを効率よく実行したい場合に活用できます。
description の原文を見る
Vitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design
SKILL.md 本文
Vitest - モダン TypeScript テスティング
概要
Vitest は Vite を搭載した次世代テストフレームワークで、モダンな TypeScript/JavaScript プロジェクト向けに設計されています。HMR ベースのテスト実行による超高速なテスト実行、ネイティブ ESM サポート、ファーストクラスの TypeScript 統合を提供します。
主な機能:
- ⚡ Vite ネイティブ: HMR ベースの瞬間的なテスト実行 (Jest より 10~100倍高速)
- 🎯 TypeScript ファースト: 設定不要の TypeScript サポート組み込み
- 🔄 ESM ネイティブ: ネイティブ ES モジュール、async/await、トップレベル await
- 🧪 Jest 互換: 互換性のある API で簡単にマイグレーション可能
- 📸 スナップショット テスト: 組み込みスナップショット機能
- 🎨 コンポーネント テスト: React Testing Library、Vue Test Utils 統合
- 📊 カバレッジ: 組み込み v8/c8 カバレッジ (Istanbul より高速)
- 🌐 UI モード: テストデバッグ用の美しい Web UI
インストール:
npm install -D vitest
# TypeScript タイプ (通常は自動検出)
npm install -D @vitest/ui # オプション: UI モード
基本的なセットアップ
1. Vitest の設定
vitest.config.ts:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true, // グローバルで describe/it/expect を使用
environment: 'node', // または 'jsdom' (DOM テスト用)
coverage: {
provider: 'v8', // または 'istanbul'
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'dist/',
'**/*.test.ts',
'**/*.spec.ts',
],
},
include: ['**/*.{test,spec}.{ts,tsx}'],
exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
},
});
2. TypeScript 設定
tsconfig.json:
{
"compilerOptions": {
"types": ["vitest/globals"] // グローバル describe/it/expect 用
}
}
代替方法 (globals なし):
import { describe, it, expect } from 'vitest';
3. Package.json スクリプト
{
"scripts": {
"test": "vitest run", // CI モード (単一実行)
"test:watch": "vitest", // ウォッチモード (デフォルト)
"test:ui": "vitest --ui", // UI モード
"test:coverage": "vitest run --coverage"
}
}
コアテスティングパターン
基本的なテスト構造
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
describe('Calculator', () => {
let calculator: Calculator;
beforeEach(() => {
calculator = new Calculator();
});
it('adds two numbers correctly', () => {
const result = calculator.add(2, 3);
expect(result).toBe(5);
});
it('handles negative numbers', () => {
expect(calculator.add(-5, 3)).toBe(-2);
});
});
TypeScript 型テスト
import { describe, it, expectTypeOf, assertType } from 'vitest';
interface User {
id: number;
name: string;
email: string;
}
describe('型の安全性', () => {
it('正しい型を確保する', () => {
const user: User = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
};
// 型アサーション
expectTypeOf(user.id).toBeNumber();
expectTypeOf(user.name).toBeString();
expectTypeOf(user).toMatchTypeOf<User>();
// コンパイル時に型をアサート
assertType<User>(user);
});
it('関数の戻り値の型をチェック', () => {
function getUser(): User {
return { id: 1, name: 'Bob', email: 'bob@example.com' };
}
expectTypeOf(getUser).returns.toMatchTypeOf<User>();
});
});
モッキングとスパイ
vi.mock モジュールモッキング
import { describe, it, expect, vi } from 'vitest';
import { fetchUser } from './api';
import { UserService } from './UserService';
// モジュール全体をモック
vi.mock('./api', () => ({
fetchUser: vi.fn(),
}));
describe('UserService', () => {
it('ユーザーデータをフェッチする', async () => {
const mockUser = { id: 1, name: 'Alice' };
vi.mocked(fetchUser).mockResolvedValue(mockUser);
const service = new UserService();
const user = await service.getUser(1);
expect(fetchUser).toHaveBeenCalledWith(1);
expect(user).toEqual(mockUser);
});
});
vi.spyOn メソッドスパイ
import { describe, it, expect, vi } from 'vitest';
class Logger {
log(message: string) {
console.log(message);
}
}
describe('Logger スパイ', () => {
it('メソッド呼び出しを追跡', () => {
const logger = new Logger();
const spy = vi.spyOn(logger, 'log');
logger.log('Hello');
logger.log('World');
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).toHaveBeenCalledWith('Hello');
expect(spy).toHaveBeenLastCalledWith('World');
spy.mockRestore(); // オリジナルの実装を復元
});
});
モック実装
import { describe, it, expect, vi } from 'vitest';
describe('モック実装', () => {
it('カスタムモック実装を提供', () => {
const mockFn = vi.fn((x: number) => x * 2);
expect(mockFn(5)).toBe(10);
expect(mockFn).toHaveBeenCalledWith(5);
// 実装を変更
mockFn.mockImplementation((x: number) => x + 10);
expect(mockFn(5)).toBe(15);
// 1 回限りの実装
mockFn.mockImplementationOnce((x: number) => 100);
expect(mockFn(5)).toBe(100);
expect(mockFn(5)).toBe(15); // デフォルトに戻す
});
});
タイマーのモック
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
describe('タイマーモック', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.restoreAllMocks();
});
it('時間を高速進行', () => {
const callback = vi.fn();
setTimeout(callback, 1000);
vi.advanceTimersByTime(500);
expect(callback).not.toHaveBeenCalled();
vi.advanceTimersByTime(500);
expect(callback).toHaveBeenCalledTimes(1);
});
it('すべてのタイマーを実行', async () => {
const callback = vi.fn();
setTimeout(callback, 1000);
setTimeout(callback, 2000);
await vi.runAllTimersAsync();
expect(callback).toHaveBeenCalledTimes(2);
});
});
React テスト統合
React Testing Library セットアップ
npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event
npm install -D jsdom # DOM 環境用
vitest.config.ts (React):
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './src/test/setup.ts',
},
});
src/test/setup.ts:
import '@testing-library/jest-dom';
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import * as matchers from '@testing-library/jest-dom/matchers';
expect.extend(matchers);
afterEach(() => {
cleanup();
});
React コンポーネントテスト
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Counter } from './Counter';
describe('Counter コンポーネント', () => {
it('初期カウントをレンダー', () => {
render(<Counter initialCount={0} />);
expect(screen.getByText('Count: 0')).toBeInTheDocument();
});
it('ボタンクリックでカウンター加算', async () => {
const user = userEvent.setup();
render(<Counter initialCount={0} />);
const button = screen.getByRole('button', { name: /increment/i });
await user.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
it('onChange コールバック呼び出し', async () => {
const onChange = vi.fn();
const user = userEvent.setup();
render(<Counter initialCount={0} onChange={onChange} />);
await user.click(screen.getByRole('button', { name: /increment/i }));
expect(onChange).toHaveBeenCalledWith(1);
});
});
フック テスト
import { describe, it, expect } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';
describe('useCounter フック', () => {
it('デフォルト値で初期化', () => {
const { result } = renderHook(() => useCounter(0));
expect(result.current.count).toBe(0);
});
it('カウンター加算', () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
it('カウンターをリセット', () => {
const { result } = renderHook(() => useCounter(10));
act(() => {
result.current.reset();
});
expect(result.current.count).toBe(10);
});
});
Vue テスト統合
Vue Test Utils セットアップ
npm install -D @vue/test-utils @vitejs/plugin-vue
npm install -D happy-dom # jsdom より高速な代替
vitest.config.ts (Vue):
import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
globals: true,
environment: 'happy-dom',
setupFiles: './src/test/setup.ts',
},
});
Vue コンポーネントテスト
import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import Counter from './Counter.vue';
describe('Counter.vue', () => {
it('初期カウントをレンダー', () => {
const wrapper = mount(Counter, {
props: { initialCount: 5 },
});
expect(wrapper.text()).toContain('Count: 5');
});
it('ボタンクリックで加算', async () => {
const wrapper = mount(Counter, {
props: { initialCount: 0 },
});
await wrapper.find('button').trigger('click');
expect(wrapper.text()).toContain('Count: 1');
});
it('update イベント発火', async () => {
const wrapper = mount(Counter, {
props: { initialCount: 0 },
});
await wrapper.find('button').trigger('click');
expect(wrapper.emitted('update')).toBeTruthy();
expect(wrapper.emitted('update')?.[0]).toEqual([1]);
});
});
非同期テスト
Promise テスト
import { describe, it, expect } from 'vitest';
describe('非同期操作', () => {
it('Promise を解決', async () => {
const result = await Promise.resolve(42);
expect(result).toBe(42);
});
it('Promise を拒否', async () => {
await expect(Promise.reject(new Error('Failed'))).rejects.toThrow('Failed');
});
it('resolves マッチャー使用', async () => {
await expect(Promise.resolve(42)).resolves.toBe(42);
});
});
非同期関数テスト
import { describe, it, expect, vi } from 'vitest';
async function fetchData(id: number): Promise<string> {
const response = await fetch(`/api/data/${id}`);
return response.json();
}
describe('非同期関数', () => {
it('データ正常フェッチ', async () => {
global.fetch = vi.fn(() =>
Promise.resolve({
json: () => Promise.resolve('data'),
} as Response)
);
const data = await fetchData(1);
expect(data).toBe('data');
expect(fetch).toHaveBeenCalledWith('/api/data/1');
});
it('フェッチエラー処理', async () => {
global.fetch = vi.fn(() => Promise.reject(new Error('Network error')));
await expect(fetchData(1)).rejects.toThrow('Network error');
});
});
スナップショットテスト
基本的なスナップショット
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { UserCard } from './UserCard';
describe('UserCard スナップショット', () => {
it('スナップショットに一致', () => {
const { container } = render(
<UserCard name="Alice" email="alice@example.com" />
);
expect(container.firstChild).toMatchSnapshot();
});
it('インラインスナップショットに一致', () => {
const user = { id: 1, name: 'Bob' };
expect(user).toMatchInlineSnapshot(`
{
"id": 1,
"name": "Bob",
}
`);
});
});
スナップショット シリアライザー
import { describe, it, expect } from 'vitest';
expect.addSnapshotSerializer({
test: (val) => val && typeof val.toISOString === 'function',
print: (val) => `Date(${(val as Date).toISOString()})`,
});
describe('カスタムシリアライザー', () => {
it('日付を一貫してシリアライズ', () => {
const data = {
timestamp: new Date('2024-01-01T00:00:00.000Z'),
user: 'Alice',
};
expect(data).toMatchSnapshot();
});
});
カバレッジ設定
高度なカバレッジセットアップ
vitest.config.ts:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html', 'lcov'],
reportsDirectory: './coverage',
exclude: [
'node_modules/',
'dist/',
'**/*.test.ts',
'**/*.spec.ts',
'**/*.config.ts',
'**/types/',
],
thresholds: {
lines: 80,
functions: 80,
branches: 75,
statements: 80,
},
all: true, // テストされていないファイルをカバレッジレポートに含める
},
},
});
カバレッジ実行
# カバレッジ生成
npx vitest run --coverage
# UI 付きカバレッジ
npx vitest --coverage --ui
# 特定の閾値強制
npx vitest run --coverage --coverage.lines=90
Jest からのマイグレーション
API 互換性
Vitest は Jest 互換の API を提供:
// Jest 構文は Vitest で機能
import { describe, it, expect, jest } from 'vitest';
// 注意: 新しいコードでは 'jest' の代わりに 'vi' を使用
import { describe, it, expect, vi } from 'vitest';
// 両方とも機能しますが、vi が推奨
const mockFn = vi.fn(); // 推奨
const mockFn2 = jest.fn(); // これも機能
マイグレーションチェックリスト
1. 依存関係更新:
npm uninstall jest @types/jest ts-jest
npm install -D vitest @vitest/ui
2. package.json 更新:
{
"scripts": {
"test": "vitest run", // 旧: jest
"test:watch": "vitest" // 旧: jest --watch
}
}
3. jest.config.js を vitest.config.ts に置き換え:
// 旧: jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
// 新: vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
},
});
4. テストファイル更新:
// インポート変更
- import { jest } from '@jest/globals';
+ import { vi } from 'vitest';
// モック更新
- jest.fn()
+ vi.fn()
- jest.spyOn()
+ vi.spyOn()
- jest.mock()
+ vi.mock()
高度なパターン
並行テスト
import { describe, it, expect } from 'vitest';
describe.concurrent('並行テスト', () => {
it('テスト 1', async () => {
await slowOperation();
expect(true).toBe(true);
});
it('テスト 2', async () => {
await slowOperation();
expect(true).toBe(true);
});
// 両方のテストが並行実行
});
テストコンテキスト
import { describe, it, expect, beforeEach } from 'vitest';
interface TestContext {
user: { id: number; name: string };
api: ApiClient;
}
describe<TestContext>('コンテキスト付き', () => {
beforeEach((context) => {
context.user = { id: 1, name: 'Alice' };
context.api = new ApiClient();
});
it<TestContext>('コンテキスト使用', ({ user, api }) => {
expect(user.name).toBe('Alice');
expect(api).toBeDefined();
});
});
カスタムマッチャー
import { expect } from 'vitest';
expect.extend({
toBeWithinRange(received: number, floor: number, ceiling: number) {
const pass = received >= floor && received <= ceiling;
return {
pass,
message: () =>
pass
? `expected ${received} not to be within range ${floor} - ${ceiling}`
: `expected ${received} to be within range ${floor} - ${ceiling}`,
};
},
});
// 使用
expect(100).toBeWithinRange(90, 110);
ベストプラクティス
- globals: true を使用 - よりシンプルなインポート、Jest 互換
- jest より vi を優先 - 新しいコードでは Vitest ネイティブ API を使用
- v8 カバレッジを使用 - Istanbul より高速、ネイティブ ESM に対応
- 分離してテスト - 各テストは独立していること
- 外部依存関係をモック - ネットワーク、ファイルシステム、タイマー
- TypeScript を使用 - テストで完全な型安全性を実現
- CI モードでテスト実行 - CI では
vitest runを使用、ウォッチモードは非推奨 - UI モードを活用 - 失敗したテストをビジュアルにデバッグ
- describe.concurrent を使用 - 独立したテストを並列化
- テストに焦点を絞る - 可能な限り 1 テスト 1 アサーション
よくある落とし穴
❌ CI/CD で CI モード未使用:
// 間違い - ウォッチモードは CI でハング
"test": "vitest"
// 正解 - 単一実行
"test": "vitest run"
✅ 正しいアプローチ:
{
"scripts": {
"test": "vitest run", // CI 安全
"test:watch": "vitest", // 開発用
"test:ui": "vitest --ui" // デバッグ用
}
}
❌ 非同期テストで await 忘れ:
// 間違い - アサーション前にテストが完了
it('データ取得', () => {
fetchData().then(data => {
expect(data).toBeDefined(); // 実行されない!
});
});
// 正解
it('データ取得', async () => {
const data = await fetchData();
expect(data).toBeDefined();
});
❌ モッククリーンアップなし:
// 間違い - モックがテスト間でリーク
it('テスト 1', () => {
vi.spyOn(console, 'log');
// クリーンアップなし!
});
// 正解
import { afterEach } from 'vitest';
afterEach(() => {
vi.restoreAllMocks();
});
❌ 間違った環境を使用:
// 間違い - node 環境で DOM テスト
test: {
environment: 'node', // React コンポーネントテスト不可!
}
// 正解
test: {
environment: 'jsdom', // React/Vue コンポーネント用
}
リソース
- ドキュメント: https://vitest.dev
- API リファレンス: https://vitest.dev/api/
- マイグレーション ガイド: https://vitest.dev/guide/migration.html
- 例: https://github.com/vitest-dev/vitest/tree/main/examples
- UI モード: https://vitest.dev/guide/ui.html
関連スキル
Vitest を使用する際は、以下の補完的なスキルをご検討ください:
- typescript-core: 高度な TypeScript 型パターン、tsconfig、ランタイム検証
- react: React Testing Library 統合によるコンポーネント テスト
- test-driven-development: 完全な TDD ワークフロー (RED/GREEN/REFACTOR サイクル)
クイック TypeScript 型パターン (スタンドアロン使用用にインライン)
// ジェネリクスを使用した型安全なテストファクトリ
function createMockData<T extends Record<string, unknown>>(
defaults: T,
overrides?: Partial<T>
): T {
return { ...defaults, ...overrides };
}
const mockUser = createMockData(
{ id: 1, name: 'Test', email: 'test@example.com' },
{ name: 'Alice' }
);
// Zod を使用したテスト内でのランタイム検証
import { z } from 'zod';
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
});
test('API は有効なユーザーを返す', async () => {
const response = await fetch('/api/user/1');
const data = await response.json();
// ランタイム検証 + 型推論
const user = UserSchema.parse(data);
expect(user.email).toContain('@');
});
// リテラル推論用の const 型パラメーター
const createTestConfig = <const T extends Record<string, unknown>>(config: T): T => config;
const testEnv = createTestConfig({ mode: 'test', debug: false });
// 型: { mode: "test"; debug: false } (リテラルが保持される)
クイック React テスティングパターン (スタンドアロン使用用にインライン)
// React Testing Library と Vitest
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { describe, test, expect, vi } from 'vitest';
// コンポーネント テスト
describe('UserProfile', () => {
test('ユーザー情報をレンダー', () => {
const user = { id: 1, name: 'Alice', email: 'alice@example.com' };
render(<UserProfile user={user} />);
expect(screen.getByText('Alice')).toBeInTheDocument();
expect(screen.getByText('alice@example.com')).toBeInTheDocument();
});
test('フォーム送信を処理', async () => {
const onSubmit = vi.fn();
render(<UserForm onSubmit={onSubmit} />);
const user = userEvent.setup();
await user.type(screen.getByLabelText('Name'), 'Bob');
await user.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith({ name: 'Bob' });
});
});
});
// フック テスト
import { renderHook, act } from '@testing-library/react';
test('useCounter フック 加算', () => {
const { result } = renderHook(() => useCounter(0));
expect(result.current.count).toBe(0);
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
TDD ワークフロー クイックリファレンス (スタンドアロン使用用にインライン)
RED → GREEN → REFACTOR サイクル:
-
RED フェーズ: 失敗するテスト記述
test('有効な認証情報でユーザーを認証すべき', () => { const user = { username: 'alice', password: 'secret123' }; const result = authenticate(user); expect(result.isAuthenticated).toBe(true); // authenticate() が存在しないためテスト失敗 }); -
GREEN フェーズ: テストをパス
function authenticate(user: User): AuthResult { // テストをパスするための最小限コード if (user.username === 'alice' && user.password === 'secret123') { return { isAuthenticated: true }; } return { isAuthenticated: false }; } -
REFACTOR フェーズ: コード改善
function authenticate(user: User): AuthResult { // テストグリーン保持しながらクリーンアップ const hashed = hashPassword(user.password); const storedUser = database.getUser(user.username); return { isAuthenticated: storedUser?.passwordHash === hashed }; }
テスト構造: Arrange-Act-Assert (AAA)
test('ユーザー作成成功', async () => {
// Arrange: テストデータセットアップ
const userData = { username: 'alice', email: 'alice@example.com' };
// Act: アクション実行
const user = await createUser(userData);
// Assert: 結果検証
expect(user.username).toBe('alice');
expect(user.email).toBe('alice@example.com');
});
Vitest 固有 TDD 機能:
// ウォッチモード HMR 付き (即座フィードバック)
// vitest --watch
// デバッグ用 UI モード
// vitest --ui
// 変更されたテストのみ実行
// vitest --changed
// パフォーマンス テスト用ベンチマークモード
import { bench } from 'vitest';
bench('認証パフォーマンス', () => {
authenticate({ username: 'alice', password: 'secret' });
});
[完全な TypeScript、React、TDD ワークフローは、一緒にデプロイされた場合、各スキルで利用可能]
まとめ
- Vitest はモダン TypeScript テスティングの標準
- 10~100倍高速 - Vite ネイティブ HMR による Jest より
- ESM ファースト - ネイティブモジュールサポート
- Jest 互換 - 簡単マイグレーション用 API
- TypeScript ファースト - 組み込み型サポート
- コンポーネント テスト - React と Vue 対応
- v8 カバレッジ - Istanbul より高速
- UI モード - テストのビジュアル デバッグ
- 完璧な用途: モダン TypeScript プロジェクト、Vite ベースアプリ、React/Vue コンポーネント
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- bobmatnyc
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/bobmatnyc/claude-mpm-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。