@su-record/vibe 2.4.56 โ†’ 2.4.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CLAUDE.md +7 -18
  2. package/agents/compounder.md +1 -1
  3. package/agents/implementer.md +2 -1
  4. package/agents/simplifier.md +2 -1
  5. package/commands/vibe.run.md +4 -1
  6. package/commands/vibe.spec.md +56 -3
  7. package/dist/cli/index.d.ts.map +1 -1
  8. package/dist/cli/index.js +0 -4
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/cli/postinstall.js +32 -1
  11. package/dist/cli/postinstall.js.map +1 -1
  12. package/dist/cli/setup.d.ts +18 -4
  13. package/dist/cli/setup.d.ts.map +1 -1
  14. package/dist/cli/setup.js +87 -27
  15. package/dist/cli/setup.js.map +1 -1
  16. package/dist/cli/types.d.ts +6 -0
  17. package/dist/cli/types.d.ts.map +1 -1
  18. package/languages/csharp-unity.md +516 -0
  19. package/languages/gdscript-godot.md +470 -0
  20. package/languages/ruby-rails.md +489 -0
  21. package/languages/typescript-angular.md +433 -0
  22. package/languages/typescript-astro.md +416 -0
  23. package/languages/typescript-electron.md +407 -0
  24. package/languages/typescript-nestjs.md +524 -0
  25. package/languages/typescript-svelte.md +407 -0
  26. package/languages/typescript-tauri.md +366 -0
  27. package/package.json +1 -1
  28. package/skills/vibe-capabilities.md +1 -1
  29. package/vibe/constitution.md +130 -97
  30. package/vibe/rules/core/communication-guide.md +50 -56
  31. package/vibe/rules/core/development-philosophy.md +35 -36
  32. package/vibe/rules/core/quick-start.md +66 -85
  33. package/vibe/rules/quality/bdd-contract-testing.md +94 -89
  34. package/vibe/rules/quality/checklist.md +132 -132
  35. package/vibe/rules/quality/testing-strategy.md +132 -129
  36. package/vibe/rules/standards/anti-patterns.md +74 -74
  37. package/vibe/rules/standards/code-structure.md +44 -44
  38. package/vibe/rules/standards/complexity-metrics.md +63 -62
  39. package/vibe/rules/standards/naming-conventions.md +72 -72
  40. package/vibe/templates/constitution-template.md +153 -95
  41. package/vibe/templates/contract-backend-template.md +41 -32
  42. package/vibe/templates/contract-frontend-template.md +35 -30
  43. package/vibe/templates/feature-template.md +33 -33
  44. package/vibe/templates/spec-template.md +118 -96
@@ -1,54 +1,54 @@
1
- # ๐Ÿงช AI ์‹œ๋Œ€ ํ…Œ์ŠคํŠธ ์ „๋žต
1
+ # Testing Strategy for the AI Era
2
2
 
3
- ## ํ•ต์‹ฌ ์›์น™
3
+ ## Core Principles
4
4
 
5
5
  ```markdown
6
- โœ… ๋‹จ์ผ ์ฑ…์ž„ (SRP)
7
- โœ… ์ค‘๋ณต ์ฝ”๋“œ ์ œ๊ฑฐ (DRY)
8
- โœ… ์žฌ์‚ฌ์šฉ์„ฑ (Reusability)
9
- โœ… ๋‚ฎ์€ ๋ณต์žก๋„ (Low Complexity)
10
- โœ… ๊ณ„์•ฝ ์šฐ์„  ์„ค๊ณ„ (Contract-First)
6
+ โœ… Single Responsibility (SRP)
7
+ โœ… Don't Repeat Yourself (DRY)
8
+ โœ… Reusability
9
+ โœ… Low Complexity
10
+ โœ… Contract-First Design
11
11
  ```
12
12
 
13
- ## AI ์ฃผ๋„ ๊ฐœ๋ฐœ์—์„œ์˜ ํ…Œ์ŠคํŠธ ์šฐ์„ ์ˆœ์œ„
13
+ ## Test Priorities in AI-Driven Development
14
14
 
15
- ### 1. Contract Testing (์ตœ์šฐ์„ ) โญโญโญ
15
+ ### 1. Contract Testing (Highest Priority) โญโญโญ
16
16
 
17
- **๊ฐœ๋…**: ์ฝ”๋“œ ์ž‘์„ฑ ์ „์— **ํƒ€์ž…/์Šคํ‚ค๋งˆ๋กœ ๊ณ„์•ฝ์„ ์ •์˜**
17
+ **Concept**: **Define contracts with types/schemas** before writing code
18
18
 
19
- **์ด์œ **: AI๊ฐ€ ๊ณ„์•ฝ์„ ๋”ฐ๋ผ ๊ตฌํ˜„ํ•˜๋ฏ€๋กœ, ํƒ€์ž… ์•ˆ์ „์„ฑ์ด ์ž๋™ ๋ณด์žฅ๋จ
19
+ **Reason**: Since AI implements following contracts, type safety is automatically guaranteed
20
20
 
21
21
  #### Python (Pydantic)
22
22
 
23
23
  ```python
24
- # ๊ณ„์•ฝ ์ •์˜ (AI๊ฐ€ ์ด๋ฅผ ๋”ฐ๋ผ ๊ตฌํ˜„)
24
+ # Contract definition (AI implements following this)
25
25
  from pydantic import BaseModel, Field, EmailStr
26
26
 
27
27
  class CreateUserRequest(BaseModel):
28
- """์‚ฌ์šฉ์ž ์ƒ์„ฑ ๊ณ„์•ฝ"""
28
+ """User creation contract"""
29
29
  email: EmailStr
30
30
  username: str = Field(min_length=3, max_length=50)
31
31
  password: str = Field(min_length=8)
32
32
  age: int = Field(ge=0, le=150)
33
33
 
34
34
  class UserResponse(BaseModel):
35
- """์‚ฌ์šฉ์ž ์‘๋‹ต ๊ณ„์•ฝ"""
35
+ """User response contract"""
36
36
  id: str
37
37
  email: str
38
38
  username: str
39
39
  created_at: str
40
40
 
41
- # AI๊ฐ€ ์ด ๊ณ„์•ฝ์„ ์œ„๋ฐ˜ํ•  ์ˆ˜ ์—†์Œ (์ž๋™ ๊ฒ€์ฆ)
41
+ # AI cannot violate this contract (auto-validated)
42
42
  ```
43
43
 
44
44
  #### TypeScript
45
45
 
46
46
  ```typescript
47
- // ๊ณ„์•ฝ ์ •์˜
47
+ // Contract definition
48
48
  interface CreateUserRequest {
49
49
  email: string;
50
- username: string; // 3-50์ž
51
- password: string; // ์ตœ์†Œ 8์ž
50
+ username: string; // 3-50 chars
51
+ password: string; // min 8 chars
52
52
  age: number; // 0-150
53
53
  }
54
54
 
@@ -59,7 +59,7 @@ interface UserResponse {
59
59
  createdAt: string;
60
60
  }
61
61
 
62
- // Zod๋กœ ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ
62
+ // Runtime validation with Zod
63
63
  import { z } from 'zod';
64
64
 
65
65
  const createUserSchema = z.object({
@@ -73,7 +73,7 @@ const createUserSchema = z.object({
73
73
  #### Dart (Flutter)
74
74
 
75
75
  ```dart
76
- // ๊ณ„์•ฝ ์ •์˜
76
+ // Contract definition
77
77
  class CreateUserRequest {
78
78
  const CreateUserRequest({
79
79
  required this.email,
@@ -83,11 +83,11 @@ class CreateUserRequest {
83
83
  });
84
84
 
85
85
  final String email;
86
- final String username; // 3-50์ž
87
- final String password; // ์ตœ์†Œ 8์ž
86
+ final String username; // 3-50 chars
87
+ final String password; // min 8 chars
88
88
  final int age; // 0-150
89
89
 
90
- // JSON ์ง๋ ฌํ™” (๊ณ„์•ฝ ๊ฐ•์ œ)
90
+ // JSON serialization (contract enforcement)
91
91
  Map<String, dynamic> toJson() => {
92
92
  'email': email,
93
93
  'username': username,
@@ -97,24 +97,24 @@ class CreateUserRequest {
97
97
  }
98
98
  ```
99
99
 
100
- ### 2. Integration Testing (๋†’์Œ) โญโญโญ
100
+ ### 2. Integration Testing (High) โญโญโญ
101
101
 
102
- **๊ฐœ๋…**: ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” **์‹ค์ œ ์‹œ๋‚˜๋ฆฌ์˜ค ํ…Œ์ŠคํŠธ**
102
+ **Concept**: **Test real scenarios** where multiple modules work together
103
103
 
104
- **์ด์œ **: AI๊ฐ€ ๋†“์นœ ๋ชจ๋“ˆ ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌ
104
+ **Reason**: Discovers module interaction errors that AI may have missed
105
105
 
106
106
  ```python
107
- # โœ… ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ: ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„
107
+ # โœ… Integration test: Real business flow
108
108
  @pytest.mark.asyncio
109
109
  async def test_user_registration_flow():
110
110
  """
111
- ์‹œ๋‚˜๋ฆฌ์˜ค: ์‹ ๊ทœ ์‚ฌ์šฉ์ž ๊ฐ€์ž…
112
- 1. ์ด๋ฉ”์ผ ์ค‘๋ณต ์ฒดํฌ
113
- 2. ์‚ฌ์šฉ์ž ์ƒ์„ฑ
114
- 3. ํ™˜์˜ ์ด๋ฉ”์ผ ๋ฐœ์†ก
115
- 4. ๊ธฐ๋ณธ ์„ค์ • ์ƒ์„ฑ
111
+ Scenario: New user registration
112
+ 1. Check email duplication
113
+ 2. Create user
114
+ 3. Send welcome email
115
+ 4. Create default settings
116
116
  """
117
- # Given: ์‹ ๊ทœ ์‚ฌ์šฉ์ž ์ •๋ณด
117
+ # Given: New user information
118
118
  request = CreateUserRequest(
119
119
  email="new@example.com",
120
120
  username="newuser",
@@ -122,50 +122,50 @@ async def test_user_registration_flow():
122
122
  age=25,
123
123
  )
124
124
 
125
- # When: ํšŒ์›๊ฐ€์ž… API ํ˜ธ์ถœ
125
+ # When: Call registration API
126
126
  response = await client.post("/api/users", json=request.dict())
127
127
 
128
- # Then: ์‚ฌ์šฉ์ž ์ƒ์„ฑ ์„ฑ๊ณต
128
+ # Then: User creation succeeds
129
129
  assert response.status_code == 201
130
130
  data = response.json()
131
131
  assert data["email"] == "new@example.com"
132
132
 
133
- # And: ํ™˜์˜ ์ด๋ฉ”์ผ ๋ฐœ์†ก ํ™•์ธ
133
+ # And: Welcome email sent
134
134
  assert email_service.sent_count == 1
135
135
 
136
- # And: ๊ธฐ๋ณธ ์„ค์ • ์ƒ์„ฑ ํ™•์ธ
136
+ # And: Default settings created
137
137
  settings = await get_user_settings(data["id"])
138
138
  assert settings is not None
139
139
  ```
140
140
 
141
141
  ```typescript
142
- // โœ… ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ: React ์ปดํฌ๋„ŒํŠธ + API
142
+ // โœ… Integration test: React component + API
143
143
  import { render, screen, waitFor } from '@testing-library/react';
144
144
  import userEvent from '@testing-library/user-event';
145
145
  import { UserRegistration } from './UserRegistration';
146
146
 
147
147
  test('user can register successfully', async () => {
148
- // Given: ํšŒ์›๊ฐ€์ž… ํผ ๋ Œ๋”๋ง
148
+ // Given: Render registration form
149
149
  render(<UserRegistration />);
150
150
 
151
- // When: ์‚ฌ์šฉ์ž๊ฐ€ ํผ ์ž…๋ ฅ
151
+ // When: User fills form
152
152
  await userEvent.type(screen.getByLabelText('Email'), 'new@example.com');
153
153
  await userEvent.type(screen.getByLabelText('Username'), 'newuser');
154
154
  await userEvent.type(screen.getByLabelText('Password'), 'password123');
155
155
  await userEvent.click(screen.getByRole('button', { name: 'Sign Up' }));
156
156
 
157
- // Then: ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
157
+ // Then: Success message displayed
158
158
  await waitFor(() => {
159
159
  expect(screen.getByText('Welcome!')).toBeInTheDocument();
160
160
  });
161
161
  });
162
162
  ```
163
163
 
164
- ### 3. Property-Based Testing (์ค‘๊ฐ„) โญโญ
164
+ ### 3. Property-Based Testing (Medium) โญโญ
165
165
 
166
- **๊ฐœ๋…**: ์ž…๋ ฅ ๋ฒ”์œ„ ์ „์ฒด๋ฅผ **์ž๋™ ์ƒ์„ฑํ•˜์—ฌ ํ…Œ์ŠคํŠธ**
166
+ **Concept**: **Automatically generate inputs** across entire input range to test
167
167
 
168
- **์ด์œ **: AI๊ฐ€ ์ƒ๊ฐ ๋ชปํ•œ ์—ฃ์ง€ ์ผ€์ด์Šค๋ฅผ ์ž๋™์œผ๋กœ ๋ฐœ๊ฒฌ
168
+ **Reason**: Automatically discovers edge cases AI didn't think of
169
169
 
170
170
  ```python
171
171
  # โœ… Property-based testing (Hypothesis)
@@ -177,7 +177,7 @@ from hypothesis import given, strategies as st
177
177
  username=st.text(min_size=3, max_size=50),
178
178
  )
179
179
  def test_user_creation_with_any_valid_input(age, email, username):
180
- """๋ชจ๋“  ์œ ํšจํ•œ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๊ฐ€๋Šฅ"""
180
+ """User creation possible with any valid input"""
181
181
  user = create_user(email=email, username=username, age=age)
182
182
  assert user.age == age
183
183
  assert user.email == email
@@ -190,8 +190,8 @@ import fc from 'fast-check';
190
190
  test('discount calculation always returns valid percentage', () => {
191
191
  fc.assert(
192
192
  fc.property(
193
- fc.float({ min: 0, max: 10000 }), // ๊ฐ€๊ฒฉ
194
- fc.float({ min: 0, max: 1 }), // ํ• ์ธ์œจ
193
+ fc.float({ min: 0, max: 10000 }), // price
194
+ fc.float({ min: 0, max: 1 }), // discount rate
195
195
  (price, rate) => {
196
196
  const discount = calculateDiscount(price, rate);
197
197
  return discount >= 0 && discount <= price;
@@ -201,22 +201,22 @@ test('discount calculation always returns valid percentage', () => {
201
201
  });
202
202
  ```
203
203
 
204
- ### 4. Unit Testing (๋‚ฎ์Œ, ์„ ํƒ์ ) โญ
204
+ ### 4. Unit Testing (Low, Selective) โญ
205
205
 
206
- **๊ฐœ๋…**: ๊ฐœ๋ณ„ ํ•จ์ˆ˜/๋ฉ”์„œ๋“œ ํ…Œ์ŠคํŠธ
206
+ **Concept**: Test individual functions/methods
207
207
 
208
- **์–ธ์ œ ์ž‘์„ฑ**: **๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋งŒ** ์„ ํƒ์ ์œผ๋กœ
208
+ **When to write**: **Only for complex business logic** selectively
209
209
 
210
210
  ```python
211
- # โœ… Unit Test: ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™
211
+ # โœ… Unit Test: Complex business rules
212
212
  def test_tier_selection_score_calculation():
213
213
  """
214
- ๋Œ€์žฅ๊ธˆ ์„ ๋ฐœ ์ ์ˆ˜ ๊ณ„์‚ฐ (๋ณต์žกํ•œ ๊ฐ€์ค‘์น˜)
215
- - ํ”ผ๋“œ ร—1.15
214
+ Selection score calculation (complex weights)
215
+ - Feed ร—1.15
216
216
  - OCR ร—1.2
217
- - ์ข‹์•„์š” ร—1.0
218
- - ๋ถ๋งˆํฌ ร—1.0
219
- - ์—ฐ๊ณ„ ร—1.5
217
+ - Likes ร—1.0
218
+ - Bookmarks ร—1.0
219
+ - Partnerships ร—1.5
220
220
  """
221
221
  score = calculate_selection_score(
222
222
  feeds=10, # 10 ร— 1.15 = 11.5
@@ -227,73 +227,73 @@ def test_tier_selection_score_calculation():
227
227
  )
228
228
  assert score == 48.5
229
229
 
230
- # โŒ ๋ถˆํ•„์š”ํ•œ Unit Test: ๋‹จ์ˆœ CRUD
230
+ # โŒ Unnecessary Unit Test: Simple CRUD
231
231
  def test_get_user_by_id():
232
- """Integration Test๋กœ ์ถฉ๋ถ„"""
232
+ """Integration Test is sufficient"""
233
233
  user = get_user("user-123")
234
- assert user.id == "user-123" # ์˜๋ฏธ ์—†์Œ
234
+ assert user.id == "user-123" # Meaningless
235
235
  ```
236
236
 
237
- ### 5. E2E Testing (์‹œ๋‚˜๋ฆฌ์˜ค ๊ฒ€์ฆ) โญโญ
237
+ ### 5. E2E Testing (Scenario Verification) โญโญ
238
238
 
239
- **๊ฐœ๋…**: ์‚ฌ์šฉ์ž ๊ด€์ ์˜ ์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค ํ…Œ์ŠคํŠธ
239
+ **Concept**: Test complete scenarios from user perspective
240
240
 
241
- **์–ธ์ œ**: ์ฃผ์š” ์‚ฌ์šฉ์ž ํ”Œ๋กœ์šฐ๋งŒ ์„ ํƒ์ ์œผ๋กœ
241
+ **When**: Only selectively for major user flows
242
242
 
243
243
  ```typescript
244
244
  // โœ… E2E Test: Playwright/Cypress
245
245
  test('user can complete full registration flow', async ({ page }) => {
246
- // 1. ํ™ˆํŽ˜์ด์ง€ ์ ‘์†
246
+ // 1. Visit homepage
247
247
  await page.goto('https://app.example.com');
248
248
 
249
- // 2. ํšŒ์›๊ฐ€์ž… ํด๋ฆญ
249
+ // 2. Click sign up
250
250
  await page.click('text=Sign Up');
251
251
 
252
- // 3. ํผ ์ž…๋ ฅ
252
+ // 3. Fill form
253
253
  await page.fill('input[name="email"]', 'test@example.com');
254
254
  await page.fill('input[name="username"]', 'testuser');
255
255
  await page.fill('input[name="password"]', 'password123');
256
256
 
257
- // 4. ์ œ์ถœ
257
+ // 4. Submit
258
258
  await page.click('button[type="submit"]');
259
259
 
260
- // 5. ๋Œ€์‹œ๋ณด๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ™•์ธ
260
+ // 5. Verify redirect to dashboard
261
261
  await expect(page).toHaveURL('/dashboard');
262
262
  await expect(page.locator('h1')).toContainText('Welcome, testuser!');
263
263
  });
264
264
  ```
265
265
 
266
- ## ํ…Œ์ŠคํŠธ ์šฐ์„ ์ˆœ์œ„ ๊ฒฐ์ • ํŠธ๋ฆฌ
266
+ ## Test Priority Decision Tree
267
267
 
268
268
  ```
269
- ์ƒˆ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์‹œ:
269
+ When developing new features:
270
270
 
271
- 1. Contract ์ •์˜ํ–ˆ๋Š”๊ฐ€?
272
- No โ†’ Contract ๋จผ์ € ์ž‘์„ฑ (Pydantic/Zod/Dart class)
271
+ 1. Did you define contracts?
272
+ No โ†’ Write contracts first (Pydantic/Zod/Dart class)
273
273
  Yes โ†’ โฌ‡๏ธ
274
274
 
275
- 2. ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ํ˜‘๋ ฅํ•˜๋Š”๊ฐ€?
276
- Yes โ†’ Integration Test ์ž‘์„ฑ โญโญโญ
275
+ 2. Do multiple modules collaborate?
276
+ Yes โ†’ Write Integration Test โญโญโญ
277
277
  No โ†’ โฌ‡๏ธ
278
278
 
279
- 3. ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ธ๊ฐ€? (๋ณต์žก๋„ > 10)
280
- Yes โ†’ Unit Test ์ž‘์„ฑ โญ
279
+ 3. Is it complex business logic? (complexity > 10)
280
+ Yes โ†’ Write Unit Test โญ
281
281
  No โ†’ โฌ‡๏ธ
282
282
 
283
- 4. ํ•ต์‹ฌ ์‚ฌ์šฉ์ž ํ”Œ๋กœ์šฐ์ธ๊ฐ€?
284
- Yes โ†’ E2E Test ์ž‘์„ฑ โญโญ
285
- No โ†’ ์™„๋ฃŒ โœ…
283
+ 4. Is it a core user flow?
284
+ Yes โ†’ Write E2E Test โญโญ
285
+ No โ†’ Done โœ…
286
286
  ```
287
287
 
288
- ## AI ์‹œ๋Œ€์˜ TDD ๋Œ€์•ˆ: ATDD (AI-Test-Driven Development)
288
+ ## TDD Alternative for AI Era: ATDD (AI-Test-Driven Development)
289
289
 
290
290
  ```markdown
291
- # ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ ํ๋ฆ„
291
+ # New development flow
292
292
 
293
- 1. **์š”๊ตฌ์‚ฌํ•ญ ๋ช…ํ™•ํ™”** (๊ฐœ๋ฐœ์ž)
294
- "ํ”„๋ฆฌ๋ฏธ์—„ ์‚ฌ์šฉ์ž๋Š” 10% ํ• ์ธ์„ ๋ฐ›๋Š”๋‹ค"
293
+ 1. **Clarify requirements** (Developer)
294
+ "Premium users get 10% discount"
295
295
 
296
- 2. **Contract ์ •์˜** (๊ฐœ๋ฐœ์ž)
296
+ 2. **Define contracts** (Developer)
297
297
  interface DiscountRequest {
298
298
  userId: string;
299
299
  orderTotal: number;
@@ -305,28 +305,29 @@ test('user can complete full registration flow', async ({ page }) => {
305
305
  discountRate: number;
306
306
  }
307
307
 
308
- 3. **ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ** (๊ฐœ๋ฐœ์ž or AI)
308
+ 3. **Write test scenarios** (Developer or AI)
309
309
  test('premium user gets 10% discount', () => {
310
- // Given: ํ”„๋ฆฌ๋ฏธ์—„ ์œ ์ €, 100์› ์ฃผ๋ฌธ
311
- // When: ํ• ์ธ ๊ณ„์‚ฐ
312
- // Then: 90์› (10% ํ• ์ธ)
310
+ // Given: Premium user, 100 order
311
+ // When: Calculate discount
312
+ // Then: 90 (10% discount)
313
313
  })
314
314
 
315
- 4. **AI๊ฐ€ ๊ตฌํ˜„** (AI)
316
- - Contract๋ฅผ ๋”ฐ๋ผ ์ฝ”๋“œ ์ƒ์„ฑ
317
- - ํ…Œ์ŠคํŠธ ํ†ต๊ณผํ•˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑ
315
+ 4. **AI implements** (AI)
316
+ - Generate code following contracts
317
+ - Write code that passes tests
318
318
 
319
- 5. **ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ** (์ž๋™)
320
- - CI/CD์—์„œ ์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค ๊ฒ€์ฆ
319
+ 5. **Integration test** (Automated)
320
+ - Verify complete scenarios in CI/CD
321
321
 
322
- 6. **๋ฆฌํŒฉํ† ๋ง** (AI + ๊ฐœ๋ฐœ์ž)
323
- - ๋ณต์žก๋„, ์ค‘๋ณต ์ œ๊ฑฐ
324
- - SRP ์ค€์ˆ˜ ํ™•์ธ
322
+ 6. **Refactoring** (AI + Developer)
323
+ - Remove complexity, duplication
324
+ - Verify SRP compliance
325
325
  ```
326
326
 
327
- ## ์–ธ์–ด๋ณ„ ๋„๊ตฌ
327
+ ## Language-specific Tools
328
328
 
329
329
  ### Python
330
+
330
331
  ```bash
331
332
  # Contract Testing
332
333
  pip install pydantic
@@ -342,6 +343,7 @@ pip install pytest-cov
342
343
  ```
343
344
 
344
345
  ### TypeScript/JavaScript
346
+
345
347
  ```bash
346
348
  # Contract Testing
347
349
  npm install zod
@@ -357,6 +359,7 @@ npm install playwright
357
359
  ```
358
360
 
359
361
  ### Dart/Flutter
362
+
360
363
  ```bash
361
364
  # Integration Testing
362
365
  flutter pub add integration_test
@@ -368,29 +371,29 @@ flutter test
368
371
  flutter drive --target=test_driver/app.dart
369
372
  ```
370
373
 
371
- ## ์•ˆํ‹ฐํŒจํ„ด
374
+ ## Anti-patterns
372
375
 
373
376
  ```python
374
- # โŒ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ ํ…Œ์ŠคํŠธ (๊นจ์ง€๊ธฐ ์‰ฌ์›€)
377
+ # โŒ Testing implementation details (fragile)
375
378
  def test_internal_cache_structure():
376
379
  service = UserService()
377
- assert service._cache == {} # ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กด
380
+ assert service._cache == {} # Depends on internal implementation
378
381
 
379
- # โœ… ๊ณต๊ฐœ API ํ…Œ์ŠคํŠธ (๊ฒฌ๊ณ ํ•จ)
382
+ # โœ… Testing public API (robust)
380
383
  def test_user_data_is_cached_after_first_call():
381
384
  service = UserService()
382
385
  user1 = service.get_user("123")
383
386
  user2 = service.get_user("123")
384
- assert user1 is user2 # ๋™์ž‘๋งŒ ๊ฒ€์ฆ
387
+ assert user1 is user2 # Only verify behavior
385
388
  ```
386
389
 
387
390
  ```typescript
388
- // โŒ ๋ชจ๋“  ํ•จ์ˆ˜์— Unit Test (๊ณผ๋„ํ•จ)
391
+ // โŒ Unit tests for every function (excessive)
389
392
  test('add function adds two numbers', () => {
390
- expect(add(1, 2)).toBe(3); // ์˜๋ฏธ ์—†์Œ
393
+ expect(add(1, 2)).toBe(3); // Meaningless
391
394
  });
392
395
 
393
- // โœ… ๋ณต์žกํ•œ ๋กœ์ง๋งŒ ํ…Œ์ŠคํŠธ
396
+ // โœ… Only test complex logic
394
397
  test('calculate shipping cost with multiple conditions', () => {
395
398
  const cost = calculateShipping({
396
399
  weight: 10,
@@ -398,40 +401,40 @@ test('calculate shipping cost with multiple conditions', () => {
398
401
  isPremium: true,
399
402
  isExpress: false,
400
403
  });
401
- expect(cost).toBe(45); // ๋ณต์žกํ•œ ๊ทœ์น™ ๊ฒ€์ฆ
404
+ expect(cost).toBe(45); // Verify complex rules
402
405
  });
403
406
  ```
404
407
 
405
- ## ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ชฉํ‘œ
408
+ ## Test Coverage Goals
406
409
 
407
410
  ```markdown
408
- # ํ˜„์‹ค์ ์ธ ๋ชฉํ‘œ
411
+ # Realistic goals
409
412
 
410
- - Contract Coverage: 100% (๋ชจ๋“  API๋Š” ์Šคํ‚ค๋งˆ ์ •์˜)
411
- - Integration Coverage: 80% (์ฃผ์š” ๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„)
412
- - Unit Coverage: ์„ ํƒ์  (๋ณต์žกํ•œ ๋กœ์ง๋งŒ)
413
- - E2E Coverage: 20-30% (ํ•ต์‹ฌ ์‚ฌ์šฉ์ž ํ”Œ๋กœ์šฐ)
413
+ - Contract Coverage: 100% (All APIs have schema definitions)
414
+ - Integration Coverage: 80% (Major business flows)
415
+ - Unit Coverage: Selective (Complex logic only)
416
+ - E2E Coverage: 20-30% (Core user flows)
414
417
 
415
- # โŒ ํ”ผํ•ด์•ผ ํ•  ๊ฒƒ
416
- - 100% Unit Test Coverage (์‹œ๊ฐ„ ๋‚ญ๋น„)
417
- - ๋‹จ์ˆœ CRUD์— Unit Test (Integration์œผ๋กœ ์ถฉ๋ถ„)
418
- - ๋ชจ๋“  ์—ฃ์ง€ ์ผ€์ด์Šค ์ˆ˜๋™ ํ…Œ์ŠคํŠธ (Property-based ์‚ฌ์šฉ)
418
+ # โŒ Avoid
419
+ - 100% Unit Test Coverage (waste of time)
420
+ - Unit Tests for simple CRUD (Integration is sufficient)
421
+ - Manual testing all edge cases (use Property-based)
419
422
  ```
420
423
 
421
- ## ํ•ต์‹ฌ ์š”์•ฝ
424
+ ## Key Summary
422
425
 
423
426
  ```markdown
424
- AI ์‹œ๋Œ€ ํ…Œ์ŠคํŠธ ์ „๋žต:
425
-
426
- 1. โœ… Contract-First (ํƒ€์ž…/์Šคํ‚ค๋งˆ ๋จผ์ €)
427
- 2. โœ… Integration Testing (์‹ค์ œ ์‹œ๋‚˜๋ฆฌ์˜ค)
428
- 3. โš ๏ธ Unit Testing (๋ณต์žกํ•œ ๋กœ์ง๋งŒ)
429
- 4. โŒ ์ „ํ†ต์  TDD (AI ์‹œ๋Œ€์—” ๋น„ํšจ์œจ)
430
-
431
- ๋ชฉํ‘œ:
432
- - ๋‹จ์ผ ์ฑ…์ž„ (SRP)
433
- - ์ค‘๋ณต ์ œ๊ฑฐ (DRY)
434
- - ์žฌ์‚ฌ์šฉ์„ฑ
435
- - ๋‚ฎ์€ ๋ณต์žก๋„
436
- - ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ
427
+ AI Era Testing Strategy:
428
+
429
+ 1. โœ… Contract-First (types/schemas first)
430
+ 2. โœ… Integration Testing (real scenarios)
431
+ 3. โš ๏ธ Unit Testing (complex logic only)
432
+ 4. โŒ Traditional TDD (inefficient in AI era)
433
+
434
+ Goals:
435
+ - Single Responsibility (SRP)
436
+ - No Duplication (DRY)
437
+ - Reusability
438
+ - Low Complexity
439
+ - Fast Feedback
437
440
  ```