# π― World-Class Tester Persona
**λ²μ© μννΈμ¨μ΄ ν
μ€ν
ν΅μ¬ μ€μ κ°μ΄λ**
> λͺ¨λ μΉ μ ν리μΌμ΄μ
νλ‘μ νΈμ μ μ© κ°λ₯ν World-Class ν
μ€ν
λ°©λ²λ‘ μ
λλ€.
---
## π λͺ©μ°¨
1. [μλ‘ : ν
μ€νΈμ μ€μμ±](#μλ‘ )
2. [ν΅μ¬ ν
μ€ν
μν¬νλ‘μ°](#ν΅μ¬-ν
μ€ν
-μν¬νλ‘μ°)
3. [Manual Testing μ€μ ](#manual-testing-μ€μ )
4. [E2E μλν ν
μ€ν
](#e2e-μλν-ν
μ€ν
)
5. [λ²κ·Έ 리ν¬νΈ μμ±λ²](#λ²κ·Έ-리ν¬νΈ-μμ±λ²)
6. [Pre-release κ²μ¦](#pre-release-κ²μ¦)
---
## μλ‘
### ν
μ€νΈκ° μ€μν μ΄μ
**IEEE Software** μ°κ΅¬μ λ°λ₯΄λ©΄ ν
μ€νΈλ **νλ‘μ νΈμ 40-50%**λ₯Ό μ°¨μ§νλ ν΅μ¬ νλμ
λλ€.
#### ν
μ€νΈκ° ν΄κ²°νλ λ¬Έμ
- β
**κΈ°λ₯ κ²°ν¨ λ°κ²¬**: μꡬμ¬ν λ―Έλ¬μ± μλ³
- β
**μ¬μ©μ κ²½ν κ²μ¦**: μ€μ¬μ© νκ²½ νΈμμ± νμΈ
- β
**νκ· κ²°ν¨ λ°©μ§**: κΈ°μ‘΄ κΈ°λ₯ 보νΈ
- β
**μ±λ₯/보μ κ²μ¦**: μλ, μμ μ±, μ·¨μ½μ μ κ²
#### ν
μ€νΈ νΌλΌλ―Έλ
```
/\
/E2E\ β κ°μ₯ μ κ² (λλ¦¬κ³ λΉμ)
/------\
/ API \ β μ€κ° μ λ
/----------\
/ Unit \ β κ°μ₯ λ§μ΄ (λΉ λ₯΄κ³ μ λ ΄)
/--------------\
```
| λ 벨 | λΉμ¨ | μ€ν λΉλ | λꡬ |
|------|------|----------|------|
| E2E | 10% | Daily | Playwright, Cypress |
| Integration | 20% | λ§€ μ»€λ° | Vitest, Supertest |
| Unit | 70% | λ§€ μ»€λ° | Vitest, Jest |
---
## ν΅μ¬ ν
μ€ν
μν¬νλ‘μ°
### 1. μꡬμ¬ν λΆμ
#### ν΅μ¬ μ§λ¬Έ 체ν¬λ¦¬μ€νΈ
```markdown
π ν
μ€νΈ μ€κ³ μ νμ μ§λ¬Έ:
- [ ] μ΄ κΈ°λ₯μ λͺ©μ μ 무μμΈκ°?
- [ ] μ±κ³΅ κΈ°μ€μ?
- [ ] μμΈ μν©μ μ΄λ»κ² μ²λ¦¬νλκ°?
- [ ] μ±λ₯ μꡬμ¬νμ΄ μλκ°?
- [ ] μ κ·Όμ± κ³ λ €μ¬νμ?
- [ ] 보μ μνμ μλκ°?
```
#### ν
μ€νΈ λ²μ μ μ μμ
**κΈ°λ₯: AI Chat**
```
β
In Scope:
- λ©μμ§ μ‘μμ
- AI μλ΅ λ λλ§
- λν νμ€ν 리 μ μ§
- μλ¬ μ²λ¦¬ (API μ€ν¨, νμμμ)
- λ§ν¬λ€μ΄ λ λλ§
β Out of Scope (Phase 2):
- λ©ν°λͺ¨λ¬ (μ΄λ―Έμ§)
- μμ± μ
λ ₯
- κ²μ κΈ°λ₯
```
### 2. ν
μ€νΈ μΌμ΄μ€ μ€κ³
#### Happy Path, Error Path, Edge Cases
```typescript
// μμ: Login Feature
// β
Happy Path
TC001: μ ν¨ν μ격μ¦λͺ
μΌλ‘ λ‘κ·ΈμΈ μ±κ³΅
TC002: "Remember me" μ²΄ν¬ μ μΈμ
μ μ§
// β οΈ Error Paths
TC003: μλͺ»λ μ΄λ©μΌ β μλ¬ λ©μμ§
TC004: μλͺ»λ λΉλ°λ²νΈ β μλ¬ λ©μμ§
TC005: λ€νΈμν¬ μ€λ₯ β μ¬μλ μλ΄
// π₯ Edge Cases
TC006: SQL injection μλ β μ°¨λ¨
TC007: 256μ νΉμλ¬Έμ λΉλ°λ²νΈ
TC008: λμ λ€μ€ λ‘κ·ΈμΈ
```
---
## Manual Testing μ€μ
### νκ²½ μ€μ
#### Chrome DevTools νμ λ¨μΆν€
```bash
F12 # DevTools μ΄κΈ°
Ctrl+Shift+M # λͺ¨λ°μΌ λ·°
Ctrl+Shift+C # μμ μ ν
Ctrl+Shift+I # Console
# Network ν μ²΄ν¬ νλͺ©
β Status codes (200, 400, 500)
β Response times (β€3μ΄)
β Failed requests (λΉ¨κ°μ)
β Payload ν¬κΈ°
```
### Manual Testing 4λ¨κ³
#### Step 1: μ€λΉ
```markdown
β
μμ μ 체ν¬λ¦¬μ€νΈ:
- [ ] μ΅μ λΈλΌμ°μ (Chrome/Firefox/Safari)
- [ ] DevTools Network ν ON
- [ ] Console μλ¬ λͺ¨λν°λ§
- [ ] νλ©΄ λ
Ήν μ€λΉ (Loom/OBS)
- [ ] ν
μ€νΈ κ³μ μ€λΉ
```
#### Step 2: Happy Path
**μμ: νλ‘μ νΈ μμ±**
```
1. λ‘κ·ΈμΈ (researcher κΆν)
2. Dashboard β "Create Project"
3. μ΄λ¦: "Test Project Alpha"
4. Description μ
λ ₯
5. Start/End Date μ ν
6. "Create" ν΄λ¦
7. λ‘λ© νμΈ (β€2μ΄)
8. μ±κ³΅ λ©μμ§ νμΈ
9. νλ‘μ νΈ λ¦¬μ€νΈμμ νμΈ
10. μμΈ νμ΄μ§ 리λ€μ΄λ μ
νμΈ
β
μμ: λͺ¨λ μ
λ ₯ μ μ₯, μλ¬ μμ
```
#### Step 3: Error Path
```
Scenario: νμ νλ λλ½
1. "Create Project" ν΄λ¦
2. μ΄λ¦ μ
λ ₯ μμ΄ "Create"
3. μλ¬ λ©μμ§: "Project name is required"
4. μ
λ ₯ νλ λΉ¨κ° ν
λ리
5. ν¬μ»€μ€ μ΄λ νμΈ
```
```
Scenario: λ€νΈμν¬ μ€λ₯
1. DevTools β Offline λͺ¨λ
2. "Create" ν΄λ¦
3. μλ¬: "Network error. Please check connection."
4. Retry λ²νΌ μ 곡 νμΈ
5. μ¬μ©μ μ
λ ₯ μ μ§ νμΈ
```
#### Step 4: Edge Cases
```
Case 1: κΈ΄ μ
λ ₯
- μ΄λ¦ 500μ β UI μ κΉ¨μ§ νμΈ
- μλ² 400 μλ΅ + λͺ
νν λ©μμ§
Case 2: νΉμλ¬Έμ
- <script>alert('XSS')</script> μ
λ ₯
- XSS μ°¨λ¨ νμΈ (μ΄μ€μΌμ΄ν μ²λ¦¬)
Case 3: μ€λ³΅ μμ²
- "Create" λ²νΌ λλΈ ν΄λ¦
- μ€λ³΅ μμ± λ°©μ§
- λ²νΌ λΉνμ±ν μ²λ¦¬
```
### λ²κ·Έ λ°κ²¬ μ νλ‘μΈμ€
#### 1. νλ©΄ λ
Ήν/μ€ν¬λ¦°μ·
```
πΉ Loom λ
Ήν:
- λ²κ·Έ μ¬ν μ 체 κ³Όμ
- Console λ‘κ·Έ ν¬ν¨
- Network ν μ΄μ΄μ API μν
- μλ¬ λ©μμ§ ν΄λ‘μ¦μ
πΈ μ€ν¬λ¦°μ·:
- μλ¬ νλ©΄ μ 체
- Console λ‘κ·Έ
- Network μ€ν¨ μμ²
- μ¬μ©μ μ
λ ₯ (λ―Όκ°μ 보 μ μΈ)
```
#### 2. Console/Network λ‘κ·Έ
```javascript
// Console μλ¬ μ 체 볡μ¬
Uncaught TypeError: Cannot read 'name' of undefined
at ProjectForm.handleSubmit (ProjectForm.tsx:45)
// Network λ‘κ·Έ
POST /api/projects - 500 Internal Server Error
Response: {"error": "Database connection failed"}
```
---
## E2E μλν ν
μ€ν
### Playwright 기본 ꡬ쑰
```typescript
// playwright.config.ts
export default defineConfig({
testDir: './tests/e2e',
timeout: 30000,
use: {
baseURL: 'http://localhost:3000',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium' },
{ name: 'firefox' },
{ name: 'webkit' },
],
});
```
### Page Object Model (POM)
```typescript
// pages/LoginPage.ts
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.page.fill('[data-testid="email"]', email);
await this.page.fill('[data-testid="password"]', password);
await this.page.click('[data-testid="login-btn"]');
}
async expectSuccess() {
await expect(this.page).toHaveURL('/dashboard');
}
}
```
### μ€μ E2E μμ
**AI Chat ν
μ€νΈ**
```typescript
// tests/e2e/ai-chat.spec.ts
test('should send message and receive AI response', async ({ page }) => {
await loginAsResearcher(page);
// Navigate
await page.click('[data-testid="ai-chat-menu"]');
// Send message
await page.fill('[data-testid="chat-input"]', 'What is AI?');
await page.click('[data-testid="send-btn"]');
// Verify user message
const userMsg = page.locator('[data-testid="msg-user"]').last();
await expect(userMsg).toContainText('What is AI?');
// Wait for AI response
const aiMsg = page.locator('[data-testid="msg-ai"]').last();
await expect(aiMsg).toBeVisible({ timeout: 10000 });
await expect(aiMsg).toContainText('artificial intelligence');
});
```
**μλ¬ μ²λ¦¬ ν
μ€νΈ**
```typescript
test('should handle API error gracefully', async ({ page }) => {
// Mock API error
await page.route('**/api/ai/chat', route => {
route.fulfill({
status: 500,
body: JSON.stringify({ error: 'Service unavailable' }),
});
});
await page.click('[data-testid="ai-chat-menu"]');
await page.fill('[data-testid="chat-input"]', 'Test');
await page.click('[data-testid="send-btn"]');
// Verify error handling
const error = page.locator('[data-testid="error-alert"]');
await expect(error).toBeVisible();
await expect(error).toContainText('unavailable');
await expect(page.locator('[data-testid="retry-btn"]')).toBeVisible();
});
```
---
## λ²κ·Έ 리ν¬νΈ μμ±λ²
### JIRA/GitHub Issue ν
νλ¦Ώ
```markdown
## π λ²κ·Έ μμ½
AI Chatμμ λ©μμ§ μ€λ³΅ μ μ‘λ¨
## π νκ²½
- OS: Windows 11
- Browser: Chrome 120
- Version: v2.1.0
- User: Researcher
## π μ¬ν λ¨κ³
1. AI Chat μ΄κΈ°
2. "Test" μ
λ ₯
3. Send λ²νΌ μ°μ 2λ² ν΄λ¦
## β μ€μ κ²°κ³Ό
- λ©μμ§ 2λ² μ μ‘
- Console: TypeError
- μ±ν
μ°½μ μ€λ³΅ νμ
## β
κΈ°λ κ²°κ³Ό
- 1λ²λ§ μ μ‘
- λ²νΌ μ μ‘ μ€ λΉνμ±ν
- μλ¬ μμ
## πΉ μ¦λΉ
- Loom: https://loom.com/share/abc
- Screenshot: [첨λΆ]
- Console Log: [첨λΆ]
## π₯ μ¬κ°λ
[x] P1 - High
## π μ¬νμ¨
[x] Always (100%)
```
---
## Pre-release κ²μ¦
### νμ 체ν¬λ¦¬μ€νΈ
#### 1. CI/CD
```markdown
β
μλν:
- [ ] Unit tests 100% pass
- [ ] Integration tests pass
- [ ] E2E tests pass
- [ ] No flaky tests
- [ ] Code coverage β₯80%
```
#### 2. Critical Path (10κ°)
```markdown
β
μλ ν
μ€νΈ:
- [ ] Login/Logout
- [ ] User registration
- [ ] Create project
- [ ] Edit project
- [ ] AI Chat
- [ ] File upload/download
- [ ] Report generation
- [ ] Team invite
- [ ] Dashboard
- [ ] User settings
```
#### 3. Cross-Browser
```markdown
- [ ] Chrome (latest)
- [ ] Firefox (latest)
- [ ] Safari (latest)
- [ ] Edge (latest)
- [ ] iOS Safari
- [ ] Android Chrome
```
#### 4. Performance
```markdown
β
Lighthouse (>90):
- [ ] Performance >90
- [ ] Accessibility >95
- [ ] Best Practices >90
- [ ] SEO >90
```
#### 5. Security
```markdown
- [ ] OWASP ZAP clean
- [ ] npm audit (0 critical)
- [ ] No hardcoded secrets
- [ ] HTTPS enforced
- [ ] XSS protection
```
### Release Sign-off
```markdown
## β
Release Approval
Tested by: [Name]
Date: 2024-01-15
Version: v2.1.0
Approved by:
- [ ] QA Lead
- [ ] Engineering Lead
- [ ] Product Manager
Decision: β
GO / β NO-GO
```
---
## μ°Έκ³ μλ£
- **IEEE Software**: Software Testing Methodologies
- **Atlassian**: Manual vs Automated Testing
- **Playwright Docs**: E2E Testing Best Practices
- **OWASP**: Web Security Testing Guide
---
**π λ€μ λ¬Έμ**: [World-Class Tester Competencies](WORLD_CLASS_TESTER_COMPETENCIES.md)