| name | test-patterns |
| description | >- Use when this capability is needed. |
テストパターンガイド
プロジェクトのテスト戦略に基づいてテストを実装・レビューするためのスキル。
TESTING.md で定義されたパターンと基準を適用する。
1. テストピラミッド
/\
/E2E\ (5%) - クリティカルパス100%
/------\
/統合テスト\ (20%) - 60%以上カバレッジ
/----------\
/ユニットテスト\ (75%) - 80%以上カバレッジ
/--------------\
| テスト種別 | 比率 | カバレッジ目標 | 優先度 |
|---|
| ユニットテスト | 75% | 80%以上 | 高 |
| 統合テスト | 20% | 60%以上 | 中 |
| E2Eテスト | 5% | クリティカルパス100% | 高 |
2. カバレッジ閾値
プロジェクトの最低カバレッジ基準:
| メトリクス | 閾値 |
|---|
| branches | 70% |
| functions | 80% |
| lines | 80% |
| statements | 80% |
coverageThreshold: {
global: {
branches: 70,
functions: 80,
lines: 80,
statements: 80
}
}
3. テスト構造(AAA Pattern)
すべてのテストは Arrange-Act-Assert パターンに従うこと:
describe('UserService', () => {
let service: UserService;
let mockRepository: jest.Mocked<IUserRepository>;
beforeEach(() => {
mockRepository = mock<IUserRepository>();
service = new UserService(mockRepository);
});
describe('createUser', () => {
it('should create user successfully with valid data', async () => {
const userData = { email: 'test@example.com', name: 'Test User' };
const expectedUser = { id: '123', ...userData };
mockRepository.save.mockResolvedValue(expectedUser);
const result = await service.createUser(userData);
expect(result).toEqual(expectedUser);
expect(mockRepository.save).toHaveBeenCalledWith(
expect.objectContaining(userData)
);
});
it('should throw ValidationError for invalid email', () => {
invalidData = { : , : };
(service.(invalidData))
..();
(mockRepository.)..();
});
});
});
4. テスト命名規則
テスト名は具体的で、何をテストしているかが明確であること:
it('should return 404 when user does not exist', () => {});
it('should validate email format before saving', () => {});
it('should retry 3 times on network failure', () => {});
it('works', () => {});
it('test user', () => {});
it('error case', () => {});
5. テストの独立性
各テストは他のテストに依存しないこと:
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
service = new UserService();
});
test('test1', () => { });
test('test2', () => { });
});
let globalUser;
test('create user', () => { globalUser = createUser(); });
test('update user', () => { updateUser(globalUser); });
ルール:
beforeEach でインスタンスを再作成
- テスト間でグローバル変数を共有しない
- テストの実行順序に依存しない
6. モック・テストデータ管理
モック作成
型安全なモック生成には jest-mock-extended などのライブラリを使用する:
import { mock } from 'jest-mock-extended';
const mockRepository = mock<IUserRepository>();
データビルダーパターン
テストデータの構築には Builder パターンを使用する:
class UserBuilder {
private user: Partial<User> = {
id: '123',
email: 'default@example.com',
name: 'Default User',
};
withEmail(email: string): this {
this.user.email = email;
return this;
}
withName(name: string): this {
this.user.name = name;
return this;
}
build(): User {
return this.user as User;
}
}
const user = new UserBuilder().withEmail('custom@example.com').build();
フィクスチャ
固定のテストデータはフィクスチャファイルで管理する:
export const fixtures = {
validUser: {
id: '123',
email: 'john@example.com',
name: 'John Doe',
role: 'user',
createdAt: new Date('2024-01-01'),
},
adminUser: {
id: '456',
email: 'admin@example.com',
name: 'Admin User',
role: 'admin',
createdAt: new Date('2024-01-01'),
},
};
7. テスト種別ガイドライン
ユニットテスト
- 依存関係はすべてモック化
- 成功パスと失敗パスの両方をテスト
describe ブロックで論理的にグループ化
- 1テストにつき1アサーション(原則)
統合テスト
- テスト用データベースを使用(本番DBは使わない)
beforeAll でアプリ・DB セットアップ
afterAll でリソースクリーンアップ
beforeEach でデータベース状態をリセット
- レスポンスとデータベース状態の両方を検証
E2Eテスト
- Playwright でUI テスト、API クライアントで API テスト
- クリティカルパス(ユーザー登録、ログイン、主要フロー)を優先
- バリデーションエラーの表示も検証
- テストデータは各テストで独立して作成
8. CI/CD 統合
テストは以下の順序で CI パイプラインに組み込む:
- Lint チェック
- ユニットテスト
- 統合テスト
- E2E テスト
- カバレッジレポートアップロード
テストが失敗した場合、後続のステップは実行しない。
Converted and distributed by TomeVault — claim your Tome and manage your conversions.