@su-record/vibe 0.4.7 → 0.4.9

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.
@@ -134,11 +134,45 @@ SPEC 문서를 작성합니다 (Specification Agent).
134
134
  </acceptance>
135
135
  ```
136
136
 
137
- ### 4. Feature 파일 생성 (BDD)
137
+ ### 4. Feature 파일 생성 (BDD) - 필수
138
138
 
139
- `.vibe/features/{기능명}.feature` 생성:
140
- - SPEC의 Acceptance Criteria를 Scenario로 변환
141
- - Given-When-Then 형식
139
+ **반드시** `.vibe/features/{기능명}.feature` 파일을 생성합니다.
140
+
141
+ **생성 규칙:**
142
+ 1. SPEC의 각 Acceptance Criteria → 하나의 Scenario로 변환
143
+ 2. Happy Path (정상 케이스) + Edge Case (예외 케이스) 포함
144
+ 3. Given-When-Then 형식 준수
145
+
146
+ **Feature 구조:**
147
+ ```markdown
148
+ # Feature: {기능명}
149
+
150
+ **SPEC**: `.vibe/specs/{기능명}.md`
151
+
152
+ ## User Story
153
+ **As a** {사용자}
154
+ **I want** {기능}
155
+ **So that** {가치}
156
+
157
+ ## Scenarios
158
+
159
+ ### Scenario 1: {Happy Path}
160
+ \`\`\`gherkin
161
+ Scenario: {제목}
162
+ Given {전제}
163
+ When {행동}
164
+ Then {결과}
165
+ \`\`\`
166
+ **검증 기준**: SPEC AC #1
167
+
168
+ ### Scenario 2: {Edge Case}
169
+ ...
170
+
171
+ ## Coverage
172
+ | Scenario | SPEC AC | Status |
173
+ |----------|---------|--------|
174
+ | 1 | AC-1 | ⬜ |
175
+ ```
142
176
 
143
177
  ### 5. 품질 검증
144
178
 
@@ -5,7 +5,7 @@ argument-hint: "feature name"
5
5
 
6
6
  # /vibe.verify
7
7
 
8
- 구현된 코드를 SPEC 요구사항에 대해 검증합니다.
8
+ Feature 시나리오 기반으로 구현을 검증합니다.
9
9
 
10
10
  ## Usage
11
11
 
@@ -16,145 +16,133 @@ argument-hint: "feature name"
16
16
  ## Rules Reference
17
17
 
18
18
  **반드시 `.vibe/rules/` 규칙을 따릅니다:**
19
- - `quality/checklist.md` - 코드 품질 체크리스트 (필수)
19
+ - `quality/checklist.md` - 코드 품질 체크리스트
20
20
  - `standards/complexity-metrics.md` - 복잡도 기준
21
- - `standards/anti-patterns.md` - 안티패턴 검출
22
21
 
23
- ## Description
22
+ ## Process
24
23
 
25
- SPEC 문서의 모든 요구사항(REQ-001~N)과 비기능 요구사항(NFR)을 구현된 코드가 만족하는지 검증합니다.
24
+ ### 1. Feature 파일 로드
26
25
 
27
- ## Process
26
+ `.vibe/features/{기능명}.feature` 읽기
27
+
28
+ ### 2. 시나리오별 검증
29
+
30
+ 각 Scenario에 대해:
31
+
32
+ 1. **Given** (전제 조건) - 상태 확인
33
+ 2. **When** (행동) - 기능 실행
34
+ 3. **Then** (결과) - 예상 결과 검증
35
+
36
+ ### 3. 검증 방법
37
+
38
+ **코드 검증:**
39
+ - 해당 기능이 구현되어 있는지 확인
40
+ - Given/When/Then 각 단계가 동작하는지 확인
41
+
42
+ **테스트 실행 (있는 경우):**
43
+ - `npm test`, `pytest`, `flutter test` 등 실행
44
+ - BDD 테스트 프레임워크 결과 확인
28
45
 
29
- 1. **SPEC 문서 읽기**: `.vibe/specs/{기능명}.md`
30
- 2. **Feature 파일 읽기**: `.vibe/features/{기능명}.feature` (BDD Scenarios)
31
- 3. **TASKS 문서 확인**: 모든 Task가 ✅ 완료 상태인지 확인
32
- 4. **BDD Scenarios 검증**:
33
- - Feature 파일의 모든 Scenario 실행
34
- - Given-When-Then 각 단계 검증
35
- - Step Definitions 실행 결과 확인
36
- 5. **Contract Testing 검증**:
37
- - Provider Contract 검증 (Backend)
38
- - Consumer Contract 검증 (Frontend)
39
- - Contract 일치 여부 확인 (Pact Broker)
40
- 6. **요구사항별 검증**:
41
- - REQ-001: 6알림 카테고리 정의 → DB 스키마 확인
42
- - REQ-002: 설정 저장 (P95 < 500ms) → 성능 테스트
43
- - REQ-003: 설정 조회 (P95 < 300ms) → 성능 테스트
44
- - REQ-004: 알림 필터링 동작 → 통합 테스트
45
- - REQ-005: 기본 설정 생성 → 유닛 테스트
46
- - REQ-006: UI 피드백 → 위젯 테스트
47
- 7. **비기능 요구사항 검증**:
48
- - 성능 (Performance): Locust로 부하 테스트
49
- - 보안 (Security): JWT 인증 확인
50
- - 접근성 (Accessibility): WCAG AA 기준
51
- 8. **검증 리포트 생성**: `.vibe/reports/{기능명}-verification.md`
52
-
53
- ## Agent
54
-
55
- Quality Reviewer Agent
46
+ **수동 검증:**
47
+ - 테스트 코드가 없으면 코드 리뷰로 검증
48
+ - 시나리오의 로직이 구현되었는지 확인
49
+
50
+ ### 4. 결과 리포트
51
+
52
+ ```markdown
53
+ # Verification Report: {기능명}
54
+
55
+ ## Summary
56
+ - **총 시나리오**: N개
57
+ - **통과**: N개 ✅
58
+ - **실패**: N
59
+ - **품질 점수**: XX/100
60
+
61
+ ## Scenario Results
62
+
63
+ ### Scenario 1: {제목}
64
+ - Given: 확인됨
65
+ - When: 구현됨
66
+ - Then: 동작함
67
+ - **검증**: AC-1 충족
68
+
69
+ ### ❌ Scenario 2: {제목}
70
+ - Given: 확인됨
71
+ - When: 구현됨
72
+ - Then: **실패** - {이유}
73
+ - **수정 필요**: {구체적 내용}
74
+
75
+ ## Code Quality
76
+ - 복잡도: ✅ 적정
77
+ - 테스트 커버리지: XX%
78
+ - 에러 처리: ✅
79
+
80
+ ## Next Steps
81
+ - {실패한 시나리오 수정 방법}
82
+ ```
56
83
 
57
84
  ## Input
58
85
 
59
- - `.vibe/specs/{기능명}.md` (SPEC 문서)
60
- - `.vibe/features/{기능명}.feature` (BDD Feature 파일)
61
- - `.vibe/tasks/{기능명}.md` (TASKS 문서)
62
- - 구현된 코드 (backend/, frontend/)
63
- - BDD Step Definitions (tests/steps/, test/bdd/)
64
- - Contract 파일 (pacts/, contracts/)
86
+ - `.vibe/features/{기능명}.feature` - BDD 시나리오
87
+ - `.vibe/specs/{기능명}.md` - SPEC 문서 (참조)
88
+ - 구현된 소스 코드
65
89
 
66
90
  ## Output
67
91
 
68
- - `.vibe/reports/{기능명}-verification.md` - 검증 리포트
69
- - 통과/실패 요구사항 목록
70
- - 성능 테스트 결과
71
- - 개선 제안 사항
72
-
73
- ## Verification Checklist
74
-
75
- ### Functional Requirements
76
- - [ ] REQ-001: 6개 알림 카테고리 정의
77
- - [ ] REQ-002: 설정 저장 (P95 < 500ms)
78
- - [ ] REQ-003: 설정 조회 (P95 < 300ms)
79
- - [ ] REQ-004: 알림 필터링 동작
80
- - [ ] REQ-005: 기본 설정 생성
81
- - [ ] REQ-006: UI 피드백
82
-
83
- ### Non-Functional Requirements
84
- - [ ] 성능: P95 응답 시간 목표 달성
85
- - [ ] 보안: JWT 인증, 권한 검증
86
- - [ ] 접근성: WCAG AA 기준 (4.5:1 대비, 48x48dp 터치)
87
- - [ ] 확장성: 새 카테고리 추가 용이
88
- - [ ] 가용성: 99.9% uptime
89
-
90
- ### Code Quality (TRUST 5)
91
- - [ ] Test-first: Contract tests 작성
92
- - [ ] Readable: Docstring, Type hints
93
- - [ ] Unified: 일관된 스타일
94
- - [ ] Secured: 보안 고려
95
- - [ ] Trackable: Logging, Monitoring
96
-
97
- ### Tests
98
- - [ ] **BDD Scenarios 모두 통과** (pytest-bdd, behave, cucumber)
99
- - [ ] **Contract Tests 모두 통과** (Pact, Spring Cloud Contract)
100
- - [ ] 유닛 테스트 커버리지 > 80%
101
- - [ ] 통합 테스트 통과
102
- - [ ] E2E 테스트 통과 (실제 푸시 수신)
103
- - [ ] 성능 테스트 통과 (Locust)
92
+ - 검증 결과 리포트 (터미널 출력)
93
+ - 통과/실패 시나리오 목록
94
+ - 수정이 필요한 항목
104
95
 
105
96
  ## Example
106
97
 
107
98
  ```
108
- /vibe.verify "푸시 알림 설정 기능"
109
- ```
99
+ User: /vibe.verify "로그인"
110
100
 
111
- **결과:**
112
- ```markdown
113
- # Verification Report: 푸시 알림 설정 기능
101
+ Claude:
102
+ # Verification Report: 로그인
114
103
 
115
104
  ## Summary
116
- - **전체 요구사항**: 12
117
- - **통과**: 12개 ✅
118
- - **실패**: 0
119
- - **품질 점수**: 95/100 (A+)
120
-
121
- ## BDD Scenarios (5/5 통과)
122
- ✅ Scenario 1: 알림 설정 조회
123
- ✅ Scenario 2: 알림 카테고리 활성화
124
- Scenario 3: 알림 카테고리 비활성화
125
- Scenario 4: 기본 설정 생성
126
- Scenario 5: 설정 저장 응답 시간 검증
127
-
128
- ## Contract Tests (2/2 통과)
129
- Provider Contract: Backend API 스키마 검증
130
- Consumer Contract: Frontend 호출 규약 검증
131
-
132
- ## Functional Requirements (6/6 통과)
133
- REQ-001: 6개 알림 카테고리 정의
134
- REQ-002: 설정 저장 (P95: 420ms < 500ms)
135
- REQ-003: 설정 조회 (P95: 280ms < 300ms)
136
- REQ-004: 알림 필터링 동작
137
- ✅ REQ-005: 기본 설정 생성
138
- REQ-006: UI 피드백
139
-
140
- ## Non-Functional Requirements (4/4 통과)
141
- 성능: P95 < 500ms
142
- ✅ 보안: JWT 인증 적용
143
- 접근성: WCAG AA 준수
144
- 테스트 커버리지: 85%
145
-
146
- ## 개선 제안
147
- - 캐시 히트율 80% 달성 (현재 75%)
105
+ - **총 시나리오**: 4
106
+ - **통과**: 3개 ✅
107
+ - **실패**: 1
108
+ - **품질 점수**: 85/100
109
+
110
+ ## Scenario Results
111
+
112
+ ### ✅ Scenario 1: 유효한 자격증명으로 로그인
113
+ - Given: 사용자가 로그인 페이지에 있다 → ✅ LoginPage 컴포넌트 존재
114
+ - When: 유효한 이메일/비밀번호 입력 → ✅ handleSubmit 구현됨
115
+ - Then: 대시보드로 이동 router.push('/dashboard')
116
+
117
+ ### Scenario 2: 잘못된 비밀번호로 로그인 시도
118
+ - Given: 로그인 페이지
119
+ - When: 잘못된 비밀번호
120
+ - Then: 에러 메시지 표시 → ✅ "비밀번호가 일치하지 않습니다"
121
+
122
+ ### Scenario 3: 이메일 형식 검증
123
+ - Given: 로그인 페이지
124
+ - When: 잘못된 이메일 형식
125
+ - Then: 유효성 에러 → ✅ zod validation
126
+
127
+ ### ❌ Scenario 4: 비밀번호 찾기 링크
128
+ - Given: 로그인 페이지 → ✅
129
+ - When: "비밀번호 찾기" 클릭 → ❌ 링크 없음
130
+ - Then: 비밀번호 찾기 페이지로 이동 → ❌
131
+
132
+ ## Next Steps
133
+ Scenario 4 수정 필요:
134
+ - LoginPage에 "비밀번호 찾기" 링크 추가
135
+ - /forgot-password 라우트 구현
148
136
  ```
149
137
 
150
138
  ## Next Step
151
139
 
152
140
  검증 통과 시:
153
141
  ```
154
- vibe deploy "푸시 알림 설정 기능" # Staging 배포
142
+ 완료! 다음 기능을 진행하세요.
155
143
  ```
156
144
 
157
145
  검증 실패 시:
158
146
  ```
159
- /vibe.run "Task X-Y" # 실패한 Task 재구현
147
+ /vibe.run "기능명" --fix # 실패한 시나리오 수정
160
148
  ```
package/bin/vibe CHANGED
@@ -352,6 +352,46 @@ function removeDirRecursive(dirPath) {
352
352
  fs.rmdirSync(dirPath);
353
353
  }
354
354
 
355
+ // 최신 버전 확인 및 자동 업그레이드
356
+ async function checkAndUpgradeVibe() {
357
+ const { execSync } = require('child_process');
358
+ const currentVersion = require('../package.json').version;
359
+
360
+ try {
361
+ // npm에서 최신 버전 확인
362
+ const latestVersion = execSync('npm view @su-record/vibe version', {
363
+ encoding: 'utf-8',
364
+ stdio: ['pipe', 'pipe', 'pipe']
365
+ }).trim();
366
+
367
+ if (latestVersion !== currentVersion) {
368
+ log(` 📦 새 버전 발견: v${currentVersion} → v${latestVersion}\n`);
369
+ log(' ⬆️ vibe 업그레이드 중...\n');
370
+
371
+ execSync('npm install -g @su-record/vibe@latest', {
372
+ stdio: options.silent ? 'pipe' : 'inherit'
373
+ });
374
+
375
+ log(' ✅ vibe 업그레이드 완료!\n');
376
+
377
+ // 업그레이드 후 새 버전으로 update 재실행
378
+ log(' 🔄 새 버전으로 업데이트 재실행...\n\n');
379
+ execSync(`vibe update${options.silent ? ' --silent' : ''}`, {
380
+ stdio: 'inherit',
381
+ cwd: process.cwd()
382
+ });
383
+ return true; // 재실행됨
384
+ } else {
385
+ log(` ✅ 최신 버전 사용 중 (v${currentVersion})\n`);
386
+ return false; // 계속 진행
387
+ }
388
+ } catch (e) {
389
+ // 네트워크 오류 등은 무시하고 계속 진행
390
+ log(` ℹ️ 버전 확인 스킵 (오프라인 또는 네트워크 오류)\n`);
391
+ return false;
392
+ }
393
+ }
394
+
355
395
  // 프로젝트 업데이트
356
396
  async function update() {
357
397
  try {
@@ -366,6 +406,12 @@ async function update() {
366
406
 
367
407
  log('🔄 vibe 업데이트 중...\n');
368
408
 
409
+ // 최신 버전 확인 및 자동 업그레이드
410
+ const wasUpgraded = await checkAndUpgradeVibe();
411
+ if (wasUpgraded) {
412
+ return; // 새 버전에서 재실행됨
413
+ }
414
+
369
415
  // 마이그레이션: .agent/rules/ → .vibe/rules/
370
416
  const oldRulesDir = path.join(projectRoot, '.agent/rules');
371
417
  const oldAgentDir = path.join(projectRoot, '.agent');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "0.4.7",
3
+ "version": "0.4.9",
4
4
  "description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework",
5
5
  "bin": {
6
6
  "vibe": "./bin/vibe"
@@ -1,12 +1,8 @@
1
1
  # Feature: {기능명}
2
2
 
3
- **Generated from**: `specs/{기능명}.md`
4
- **Language**: {ko | en}
5
- **Priority**: {HIGH | MEDIUM | LOW}
3
+ **SPEC**: `.vibe/specs/{기능명}.md`
6
4
 
7
- ---
8
-
9
- ## Feature Description
5
+ ## User Story
10
6
 
11
7
  **As a** {사용자 역할}
12
8
  **I want** {원하는 기능}
@@ -14,246 +10,61 @@
14
10
 
15
11
  ---
16
12
 
17
- ## Background (Optional)
18
-
19
- ```gherkin
20
- Background:
21
- Given {공통 전제 조건 1}
22
- And {공통 전제 조건 2}
23
- ```
24
-
25
- ---
26
-
27
13
  ## Scenarios
28
14
 
29
- ### Scenario 1: {시나리오 제목}
30
-
31
- **Mapped to**: REQ-001 in SPEC
15
+ ### Scenario 1: {Happy Path - 정상 케이스}
32
16
 
33
17
  ```gherkin
34
18
  Scenario: {시나리오 제목}
35
19
  Given {전제 조건}
36
- And {추가 전제 조건}
37
20
  When {사용자 행동}
38
- And {추가 행동}
39
21
  Then {예상 결과}
40
- And {추가 검증}
41
22
  ```
42
23
 
43
- **Acceptance Criteria**:
44
- - [ ] {SPEC의 Acceptance Criteria 1}
45
- - [ ] {SPEC의 Acceptance Criteria 2}
46
-
47
- **Test Data**:
48
- ```json
49
- {
50
- "input": {...},
51
- "expected_output": {...}
52
- }
53
- ```
24
+ **검증 기준**: SPEC Acceptance Criteria #1
54
25
 
55
26
  ---
56
27
 
57
- ### Scenario 2: {에러 케이스 제목}
28
+ ### Scenario 2: {Edge Case - 예외 케이스}
58
29
 
59
30
  ```gherkin
60
- Scenario: {에러 케이스 제목}
31
+ Scenario: {에러 시나리오 제목}
61
32
  Given {전제 조건}
62
33
  When {잘못된 입력}
63
- Then {에러 응답}
64
- And {에러 메시지 검증}
34
+ Then {에러 처리}
65
35
  ```
66
36
 
37
+ **검증 기준**: SPEC Acceptance Criteria #2
38
+
67
39
  ---
68
40
 
69
- ### Scenario Outline: {파라미터화된 시나리오}
41
+ ### Scenario Outline: {파라미터화 테스트}
70
42
 
71
43
  ```gherkin
72
44
  Scenario Outline: {시나리오 제목}
73
45
  Given {전제 조건}
74
- When I {행동} with "<parameter>"
75
- Then I should see "<result>"
46
+ When I input "<input>"
47
+ Then I should see "<output>"
76
48
 
77
49
  Examples:
78
- | parameter | result |
79
- | value1 | result1 |
80
- | value2 | result2 |
81
- | value3 | result3 |
82
- ```
83
-
84
- ---
85
-
86
- ## Implementation Guide
87
-
88
- ### Backend Tests (Python + Pytest-BDD)
89
-
90
- **File**: `tests/features/{기능명}.feature`
91
-
92
- ```python
93
- # tests/step_defs/test_{기능명}.py
94
- import pytest
95
- from pytest_bdd import scenarios, given, when, then, parsers
96
-
97
- # Load scenarios
98
- scenarios('features/{기능명}.feature')
99
-
100
- @given(parsers.parse('사용자가 {role}로 로그인되어 있다'))
101
- def user_logged_in(context, role):
102
- context.user = create_user(role)
103
- context.token = authenticate(context.user)
104
-
105
- @when(parsers.parse('{action}을 실행한다'))
106
- def execute_action(context, action):
107
- context.response = api_call(action, context.token)
108
-
109
- @then(parsers.parse('응답 코드는 {status_code:d}이어야 한다'))
110
- def check_status_code(context, status_code):
111
- assert context.response.status_code == status_code
112
- ```
113
-
114
- **Run**:
115
- ```bash
116
- pytest tests/features/{기능명}.feature --verbose
117
- ```
118
-
119
- ---
120
-
121
- ### Frontend Tests (Flutter + Gherkin)
122
-
123
- **File**: `integration_test/features/{기능명}.feature`
124
-
125
- ```dart
126
- // integration_test/step_definitions/{기능명}_test.dart
127
- import 'package:flutter_gherkin/flutter_gherkin.dart';
128
-
129
- class UserLoggedInStep extends Given1WithWorld<String, FlutterWorld> {
130
- @override
131
- Future<void> executeStep(String role) async {
132
- await world.appDriver.waitForAppToSettle();
133
- // Login logic
134
- }
135
-
136
- @override
137
- RegExp get pattern => RegExp(r'사용자가 {string}로 로그인되어 있다');
138
- }
139
- ```
140
-
141
- **Run**:
142
- ```bash
143
- flutter test integration_test/{기능명}_test.dart
50
+ | input | output |
51
+ | value1 | result1 |
52
+ | value2 | result2 |
144
53
  ```
145
54
 
146
55
  ---
147
56
 
148
- ### Frontend Tests (React + Cucumber)
149
-
150
- **File**: `tests/features/{기능명}.feature`
151
-
152
- ```javascript
153
- // tests/step_definitions/{기능명}.steps.js
154
- const { Given, When, Then } = require('@cucumber/cucumber');
155
- const { render, screen, fireEvent } = require('@testing-library/react');
156
-
157
- Given('사용자가 {string}로 로그인되어 있다', async function (role) {
158
- this.user = await createUser(role);
159
- this.token = await authenticate(this.user);
160
- });
161
-
162
- When('{string}을 실행한다', async function (action) {
163
- this.response = await apiCall(action, this.token);
164
- });
57
+ ## Coverage
165
58
 
166
- Then('응답 코드는 {int}이어야 한다', function (statusCode) {
167
- expect(this.response.status).toBe(statusCode);
168
- });
169
- ```
170
-
171
- **Run**:
172
- ```bash
173
- npm test -- --features tests/features/{기능명}.feature
174
- ```
59
+ | Scenario | SPEC Acceptance | Status |
60
+ |----------|-----------------|--------|
61
+ | Scenario 1 | AC-1 | ⬜ |
62
+ | Scenario 2 | AC-2 | ⬜ |
175
63
 
176
64
  ---
177
65
 
178
- ## Tags
66
+ ## Verification
179
67
 
180
- ```gherkin
181
- @priority-high
182
- @smoke
183
- @regression
184
- @backend
185
- @frontend
186
- ```
187
-
188
- **Run by tag**:
189
68
  ```bash
190
- # Python
191
- pytest -m "priority-high"
192
-
193
- # JavaScript
194
- npm test -- --tags "@smoke"
69
+ /vibe.verify "{기능명}"
195
70
  ```
196
-
197
- ---
198
-
199
- ## Coverage Mapping
200
-
201
- | Scenario | SPEC REQ | Acceptance Criteria | Status |
202
- |----------|----------|---------------------|--------|
203
- | Scenario 1 | REQ-001 | AC-1, AC-2, AC-3 | ⬜ |
204
- | Scenario 2 | REQ-002 | AC-4, AC-5 | ⬜ |
205
- | Scenario 3 | REQ-003 | AC-6, AC-7 | ⬜ |
206
-
207
- **Coverage**: 0 / {총 시나리오 수} (0%)
208
-
209
- ---
210
-
211
- ## Test Execution Report
212
-
213
- **Last Run**: {날짜 시간}
214
- **Environment**: {dev | staging | production}
215
-
216
- | Scenario | Status | Duration | Error |
217
- |----------|--------|----------|-------|
218
- | Scenario 1 | ⬜ PENDING | - | - |
219
- | Scenario 2 | ⬜ PENDING | - | - |
220
-
221
- **Total**: 0 passed, 0 failed, {총 수} pending
222
-
223
- ---
224
-
225
- ## Next Steps
226
-
227
- 1. **구현 전 테스트 작성** (Test-First):
228
- ```bash
229
- # Create feature file first
230
- vibe feature "{기능명}"
231
-
232
- # Then implement
233
- vibe run "Task 1-1"
234
- ```
235
-
236
- 2. **구현 중 테스트 실행**:
237
- ```bash
238
- vibe test "{기능명}" --watch
239
- ```
240
-
241
- 3. **완료 후 검증**:
242
- ```bash
243
- vibe verify "{기능명}"
244
- ```
245
-
246
- ---
247
-
248
- ## Notes
249
-
250
- - ✅ **Given**: 테스트 전제 조건 (상태 설정)
251
- - ✅ **When**: 사용자 행동 (액션 실행)
252
- - ✅ **Then**: 예상 결과 (검증)
253
- - ✅ **And/But**: 추가 조건/검증
254
-
255
- **Best Practices**:
256
- - 시나리오는 비즈니스 언어로 작성
257
- - 구현 세부사항은 Step Definitions에
258
- - 각 시나리오는 독립적으로 실행 가능해야 함
259
- - Background는 중복 제거용으로만 사용