- Implement optimistic locking for deposit balance updates - Prevent race conditions in concurrent deposit requests - Add automatic retry with exponential backoff (max 3 attempts) - Add version column to user_deposits table - Improve type safety across codebase - Add explicit types for Namecheap API responses - Add typed function arguments (ManageDepositArgs, etc.) - Remove `any` types from deposit-agent and tool files - Add reconciliation job for balance integrity verification - Compare user_deposits.balance vs SUM(confirmed transactions) - Alert admin on discrepancy detection - Set up test environment with Vitest + Miniflare - Add 50+ test cases for deposit system - Add helper functions for test data creation - Update documentation - Add migration guide for version columns - Document optimistic locking patterns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
284 lines
6.9 KiB
Markdown
284 lines
6.9 KiB
Markdown
# 테스트 인프라 설치 가이드
|
|
|
|
## 개요
|
|
|
|
이 문서는 `deposit-agent.ts`에 대한 포괄적인 단위 테스트를 위한 Vitest + Miniflare 환경 설정 가이드입니다.
|
|
|
|
## 생성된 파일
|
|
|
|
```
|
|
telegram-bot-workers/
|
|
├── vitest.config.ts # Vitest 설정 (Miniflare 환경)
|
|
├── tests/
|
|
│ ├── setup.ts # D1 Database 초기화 및 헬퍼 함수
|
|
│ ├── deposit-agent.test.ts # 예치금 시스템 테스트 (50+ cases)
|
|
│ └── README.md # 테스트 가이드
|
|
├── package.json # 업데이트됨 (vitest, miniflare 추가)
|
|
├── README.md # 업데이트됨 (테스트 섹션 추가)
|
|
├── CLAUDE.md # 업데이트됨 (테스트 명령어 추가)
|
|
└── TESTING_INSTALLATION.md # 이 파일
|
|
```
|
|
|
|
## 설치 단계
|
|
|
|
### 1. 의존성 설치
|
|
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
새로 추가된 패키지:
|
|
- `vitest@^1.2.0` - 테스트 러너
|
|
- `miniflare@^3.20231030.0` - Cloudflare Workers 시뮬레이터
|
|
- `@cloudflare/vitest-pool-workers@^0.1.0` - Vitest Workers 통합
|
|
- `@vitest/coverage-v8@^1.2.0` - 커버리지 리포트
|
|
|
|
### 2. 테스트 실행
|
|
|
|
```bash
|
|
# 모든 테스트 실행
|
|
npm test
|
|
|
|
# Watch 모드 (개발 중)
|
|
npm run test:watch
|
|
|
|
# 커버리지 리포트
|
|
npm run test:coverage
|
|
```
|
|
|
|
### 3. 예상 출력
|
|
|
|
```
|
|
✓ tests/deposit-agent.test.ts (50+)
|
|
✓ executeDepositFunction
|
|
✓ get_balance (2)
|
|
✓ get_account_info (1)
|
|
✓ request_deposit - Negative Amount Validation (4)
|
|
✓ request_deposit - 7-Character Prefix Matching (4)
|
|
✓ request_deposit - Pending Transaction (2)
|
|
✓ request_deposit - Batch Failure Handling (1)
|
|
✓ get_transactions (5)
|
|
✓ cancel_transaction (5)
|
|
✓ Admin Functions - Permission Checks (3)
|
|
✓ Admin Functions - get_pending_list (2)
|
|
✓ Admin Functions - confirm_deposit (3)
|
|
✓ Admin Functions - reject_deposit (2)
|
|
✓ Concurrency Safety (2)
|
|
✓ Edge Cases (4)
|
|
✓ Unknown Function (1)
|
|
|
|
Test Files 1 passed (1)
|
|
Tests 50+ passed (50+)
|
|
Duration < 10s
|
|
```
|
|
|
|
## 테스트 범위
|
|
|
|
### 금융 작업 안전성
|
|
|
|
✅ **음수 금액 거부**
|
|
- 음수 입금 시도 → 에러 반환
|
|
- 0원 입금 시도 → 에러 반환
|
|
- 누락된 금액/입금자명 → 에러 반환
|
|
|
|
✅ **동시성 처리 안전성**
|
|
- 동일 사용자의 동시 입금 요청
|
|
- Race condition 시뮬레이션
|
|
- 3개 동시 요청 처리 검증
|
|
|
|
✅ **부분 배치 실패 처리**
|
|
- `db.batch()` 일부 실패 시뮬레이션
|
|
- `allSuccessful` 검증 로직
|
|
- 에러 throw 및 로깅 확인
|
|
|
|
✅ **입금자명 7글자 매칭**
|
|
- "홍길동아버지님" (8글자) → "홍길동아버지" (7글자) 자동 매칭
|
|
- `depositor_name_prefix` 컬럼 활용
|
|
- 금액/이름 불일치 시나리오
|
|
|
|
✅ **관리자 권한 검증**
|
|
- 비관리자의 `get_pending_list` 차단
|
|
- 비관리자의 `confirm_deposit` 차단
|
|
- 비관리자의 `reject_deposit` 차단
|
|
|
|
✅ **거래 상태 검증**
|
|
- confirmed 거래 취소 차단
|
|
- pending 거래만 확인/거절 허용
|
|
- 다른 사용자 거래 취소 차단
|
|
|
|
✅ **Edge Cases**
|
|
- 999,999,999원 (매우 큰 금액)
|
|
- "홍길동(주)" (특수문자)
|
|
- "김" (1글자 이름)
|
|
- "1234567" (정확히 7글자)
|
|
|
|
## Mock 전략
|
|
|
|
### D1 Database
|
|
|
|
Miniflare가 자동으로 in-memory SQLite 제공:
|
|
- `schema.sql` 자동 로드 (`beforeAll`)
|
|
- 각 테스트 후 데이터 정리 (`afterEach`)
|
|
- 실제 SQL 쿼리 실행 가능
|
|
|
|
### 환경 변수
|
|
|
|
`vitest.config.ts`에서 바인딩:
|
|
```typescript
|
|
bindings: {
|
|
BOT_TOKEN: 'test-bot-token',
|
|
WEBHOOK_SECRET: 'test-webhook-secret',
|
|
OPENAI_API_KEY: 'test-openai-key',
|
|
DEPOSIT_ADMIN_ID: '999999999',
|
|
}
|
|
```
|
|
|
|
### 헬퍼 함수
|
|
|
|
`tests/setup.ts`:
|
|
```typescript
|
|
createTestUser(telegramId, username) // 사용자 생성
|
|
createBankNotification(depositorName, amount) // 은행 알림 생성
|
|
createDepositTransaction(userId, amount, status) // 거래 생성
|
|
getTestDB() // DB 바인딩
|
|
```
|
|
|
|
## 디버깅
|
|
|
|
### 실패한 테스트 확인
|
|
|
|
```bash
|
|
npm test -- --reporter=verbose
|
|
```
|
|
|
|
### 특정 테스트만 실행
|
|
|
|
```bash
|
|
# 파일명 필터링
|
|
npm test deposit-agent
|
|
|
|
# 테스트 설명 필터링
|
|
npm test -- -t "should reject negative amounts"
|
|
```
|
|
|
|
### 로그 출력
|
|
|
|
```typescript
|
|
it('debugging test', async () => {
|
|
const result = await executeDepositFunction(...);
|
|
console.log('Result:', result); // 출력됨
|
|
expect(result).toBeDefined();
|
|
});
|
|
```
|
|
|
|
## 커버리지 리포트
|
|
|
|
```bash
|
|
npm run test:coverage
|
|
```
|
|
|
|
출력:
|
|
- `coverage/` 디렉토리에 HTML 리포트 생성
|
|
- 브라우저로 `coverage/index.html` 열기
|
|
|
|
## 문제 해결
|
|
|
|
### "Cannot find module" 에러
|
|
|
|
```bash
|
|
rm -rf node_modules package-lock.json
|
|
npm install
|
|
```
|
|
|
|
### Miniflare 버전 충돌
|
|
|
|
`package.json` 확인:
|
|
```json
|
|
{
|
|
"miniflare": "^3.20231030.0",
|
|
"@cloudflare/vitest-pool-workers": "^0.1.0"
|
|
}
|
|
```
|
|
|
|
### D1 스키마 초기화 실패
|
|
|
|
`tests/setup.ts`에서 경로 확인:
|
|
```typescript
|
|
const schemaPath = join(__dirname, '../schema.sql');
|
|
```
|
|
|
|
### 테스트 타임아웃
|
|
|
|
`vitest.config.ts` 수정:
|
|
```typescript
|
|
test: {
|
|
testTimeout: 10000, // 기본 5초 → 10초
|
|
}
|
|
```
|
|
|
|
## 다음 단계
|
|
|
|
### 추가 테스트 작성
|
|
|
|
1. **openai-service.ts**
|
|
- Function Calling 도구 테스트
|
|
- AI 응답 생성 테스트
|
|
|
|
2. **summary-service.ts**
|
|
- 프로필 업데이트 로직
|
|
- 3개 요약 통합 테스트
|
|
|
|
3. **Integration Tests**
|
|
- Webhook → AI → DB 전체 플로우
|
|
- Email Handler 파싱 테스트
|
|
|
|
### CI/CD 통합
|
|
|
|
**GitHub Actions** (`.github/workflows/test.yml`):
|
|
```yaml
|
|
name: Tests
|
|
|
|
on: [push, pull_request]
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-node@v3
|
|
with:
|
|
node-version: '18'
|
|
- run: npm install
|
|
- run: npm test
|
|
- run: npm run test:coverage
|
|
- uses: codecov/codecov-action@v3
|
|
```
|
|
|
|
## 참고 자료
|
|
|
|
- [Vitest 공식 문서](https://vitest.dev/)
|
|
- [Miniflare 공식 문서](https://miniflare.dev/)
|
|
- [Cloudflare Workers Testing Guide](https://developers.cloudflare.com/workers/testing/)
|
|
- [Project README](./README.md) - 프로젝트 개요 및 기능
|
|
- [Developer Guide](./CLAUDE.md) - 개발 환경 설정
|
|
- [Tests README](./tests/README.md) - 테스트 상세 가이드
|
|
|
|
## 완료 체크리스트
|
|
|
|
- [x] `vitest.config.ts` 생성
|
|
- [x] `tests/setup.ts` 생성 (D1 초기화)
|
|
- [x] `tests/deposit-agent.test.ts` 생성 (50+ test cases)
|
|
- [x] `package.json` 업데이트 (의존성 추가)
|
|
- [x] `README.md` 업데이트 (테스트 섹션)
|
|
- [x] `CLAUDE.md` 업데이트 (명령어 추가)
|
|
- [x] `tests/README.md` 생성 (가이드)
|
|
- [x] `.gitignore` 확인 (coverage/ 제외)
|
|
|
|
## 성공 기준
|
|
|
|
✅ 모든 테스트 통과 (`npm test`)
|
|
✅ 커버리지 리포트 생성 가능 (`npm run test:coverage`)
|
|
✅ 플래키 테스트 없음 (결정론적 결과)
|
|
✅ 테스트 실행 시간 <10초
|
|
✅ 명확한 테스트 설명 및 에러 메시지
|