guardia-docs/02_단위통합테스트계획서.md
DESKTOP-TKLFCPRython 938b25f286 feat(itsm): G-1~G-12 확장 기능 + 하네스/봇/설치스크립트 구현
G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현
G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건)
G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST)
G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직
G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트
G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트
G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API
G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트
G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트
G-10: core/push_notify.py + routers/push.py + PushSubscription 모델
G-11: approvals 다중승인 (위임/서명/기한초과/마감연장)
G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh

하네스: guardia-orchestrator 확장기능 Phase 반영
봇명령어: /sr /status /license /bulk 슬래시 명령어 추가
설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:18:52 +09:00

594 lines
20 KiB
Markdown

# GUARDiA ITSM + Messenger — 단위·통합 테스트 계획서
**문서 버전**: 1.0
**작성일**: 2026-05-25
**대상 시스템**: GUARDiA ITSM v1.0, GUARDiA Messenger v1.0
---
## 목차
1. [개요](#1-개요)
2. [테스트 범위 및 전략](#2-테스트-범위-및-전략)
3. [테스트 환경](#3-테스트-환경)
4. [단위 테스트 계획](#4-단위-테스트-계획)
5. [통합 테스트 계획](#5-통합-테스트-계획)
6. [비기능 테스트 계획](#6-비기능-테스트-계획)
7. [테스트 케이스 목록](#7-테스트-케이스-목록)
8. [결함 관리](#8-결함-관리)
9. [완료 기준](#9-완료-기준)
---
## 1. 개요
### 1.1 목적
본 문서는 GUARDiA ITSM 및 GUARDiA Messenger 시스템의 품질 보증을 위한 단위 테스트 및 통합 테스트 계획을 정의한다. 개별 컴포넌트의 정확성 검증(단위)과 컴포넌트 간 상호작용 검증(통합)을 통해 출시 전 결함을 조기에 발견하고 수정한다.
### 1.2 테스트 대상
| 구분 | 대상 모듈 |
|------|-----------|
| ITSM 코어 | auth, dashboard, tasks, approvals, audit, cmdb |
| ITSM 운영 | ssl_manager, pm, incidents, oncall, batch |
| ITSM 지원 | kb, shell_scripts, ssh, attachments, notifications |
| ITSM 고객 | rating, institutions, timetable, work |
| Messenger | bot dispatcher, GUARDiA_ITSM bot, command handlers |
| 공통 | scheduler, seed, database, JWT auth |
### 1.3 테스트 유형 정의
- **단위 테스트(Unit Test)**: 함수/클래스 단위의 독립 검증. 외부 의존성은 mock 처리.
- **통합 테스트(Integration Test)**: DB·Redis·SSH·Messenger 등 실제 의존성과의 연동 검증.
- **E2E 시나리오 테스트**: 사용자 시나리오 전 구간 검증 (API 호출 → DB 저장 → 알림 발송).
---
## 2. 테스트 범위 및 전략
### 2.1 단위 테스트 범위
```
범위 내 (In Scope)
├── 모든 라우터 엔드포인트 (130개 API)
├── core/scheduler.py — 스케줄 함수
├── core/seed.py — 시드 데이터 생성
├── utils/crypto.py — AES-256-GCM 암/복호화
├── utils/ssh_runner.py — SSH 명령 검증
└── schemas/*.py — Pydantic 직렬화/역직렬화
범위 외 (Out of Scope)
├── 3rd party 라이브러리 내부 (FastAPI, SQLAlchemy)
└── OS 수준 시스템 콜
```
### 2.2 통합 테스트 범위
```
범위 내
├── ITSM API ↔ SQLite DB 연동
├── ITSM API ↔ GUARDiA Messenger 알림
├── SSH 실행 → 원격 서버 응답 처리
├── SSL 점검 스크립트 → JSON 파싱
├── 스케줄러 → DB 변경 → 알림 체인
└── PM 스케줄 → WorkTimetable 자동 생성
범위 외
├── 외부 LLM API (완전 금지)
├── 실제 고객 운영 서버 대상 SSH
└── 이메일/SMS 외부 발송
```
### 2.3 테스트 전략
- **TDD 기반**: 핵심 비즈니스 로직은 테스트 먼저 작성
- **AAA 패턴**: Arrange → Act → Assert
- **픽스처 격리**: 각 테스트는 독립 SQLite in-memory DB 사용
- **커버리지 목표**: 단위 80% 이상, 통합 70% 이상
---
## 3. 테스트 환경
### 3.1 단위 테스트 환경
```
OS: 동일 (Linux/Windows 무관)
Python: 3.11+
프레임워크: pytest 8.x + pytest-asyncio
Mock: unittest.mock, respx (httpx mock)
DB: SQLite in-memory (aiosqlite)
의존성: requirements-dev.txt 참조
```
**requirements-dev.txt**:
```
pytest>=8.0
pytest-asyncio>=0.23
pytest-cov>=5.0
httpx>=0.27 # TestClient
respx>=0.21 # httpx mock
faker>=25.0 # 테스트 데이터
freezegun>=1.4 # 시간 고정
```
### 3.2 통합 테스트 환경
```
OS: Ubuntu 22.04 LTS (권장) 또는 Windows Server 2022
Python: 3.11+
DB: SQLite 파일 기반 (테스트 전용)
Messenger: 테스트 채널 (별도 구성)
SSH 대상: localhost SSH 서버 (테스트 전용)
```
### 3.3 디렉토리 구조
```
C:\GUARDiA\itsm\
└── tests\
├── conftest.py # 공통 픽스처
├── unit\
│ ├── test_auth.py
│ ├── test_tasks.py
│ ├── test_ssl_manager.py
│ ├── test_pm.py
│ ├── test_incidents.py
│ ├── test_oncall.py
│ ├── test_batch.py
│ ├── test_scheduler.py
│ └── test_crypto.py
└── integration\
├── test_sr_workflow.py
├── test_approval_chain.py
├── test_pm_workflow.py
├── test_incident_workflow.py
└── test_notification_chain.py
```
---
## 4. 단위 테스트 계획
### 4.1 conftest.py 공통 픽스처
```python
# tests/conftest.py
import pytest
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from database import Base, get_db
from main import app
TEST_DB = "sqlite+aiosqlite:///:memory:"
@pytest_asyncio.fixture
async def db_session():
engine = create_async_engine(TEST_DB)
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
SessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async with SessionLocal() as session:
yield session
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
@pytest_asyncio.fixture
async def client(db_session):
app.dependency_overrides[get_db] = lambda: db_session
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as ac:
yield ac
app.dependency_overrides.clear()
@pytest_asyncio.fixture
async def auth_headers(client):
r = await client.post("/auth/login", json={"username":"admin","password":"admin1234!"})
token = r.json()["access_token"]
return {"Authorization": f"Bearer {token}"}
```
### 4.2 인증 모듈 (auth) 단위 테스트
**파일**: `tests/unit/test_auth.py`
| 테스트 ID | 테스트명 | 설명 | 기대 결과 |
|-----------|----------|------|-----------|
| UT-AUTH-001 | 정상 로그인 | 올바른 계정으로 로그인 | 200 + access_token 반환 |
| UT-AUTH-002 | 잘못된 비밀번호 | 틀린 비밀번호 시도 | 401 Unauthorized |
| UT-AUTH-003 | 존재하지 않는 계정 | 없는 사용자명 | 401 Unauthorized |
| UT-AUTH-004 | 비밀번호 변경 | 현재 PW 확인 후 변경 | 200 + message |
| UT-AUTH-005 | JWT 토큰 만료 | 만료된 토큰으로 API 호출 | 401 Unauthorized |
| UT-AUTH-006 | RBAC — CUSTOMER 권한 제한 | CUSTOMER가 admin API 호출 | 403 Forbidden |
| UT-AUTH-007 | RBAC — ENGINEER 권한 | ENGINEER가 SR 처리 | 200 OK |
| UT-AUTH-008 | 빈 토큰 | Authorization 헤더 없음 | 401 Unauthorized |
```python
# 예시 테스트 코드
@pytest.mark.asyncio
async def test_login_success(client, db_session):
# Arrange: seed admin user
from core.seed import seed_all
await seed_all(db_session)
# Act
r = await client.post("/auth/login", json={"username":"admin","password":"admin1234!"})
# Assert
assert r.status_code == 200
data = r.json()
assert "access_token" in data
assert data["token_type"] == "bearer"
@pytest.mark.asyncio
async def test_login_wrong_password(client, db_session):
from core.seed import seed_all
await seed_all(db_session)
r = await client.post("/auth/login", json={"username":"admin","password":"wrong!"})
assert r.status_code == 401
```
### 4.3 SR 처리 (tasks) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-TASK-001 | SR 생성 (INCIDENT 유형) | 201 + sr_id 반환 |
| UT-TASK-002 | SR 생성 (CHANGE 유형) | 201 + sr_id 반환 |
| UT-TASK-003 | SR 목록 페이징 | 200 + items/total 구조 |
| UT-TASK-004 | SR 상태 변경 OPEN→IN_PROGRESS | 200 + 상태 업데이트 |
| UT-TASK-005 | SR 상태 — 잘못된 전환 | 400 Bad Request |
| UT-TASK-006 | SR 첨부파일 업로드 | 201 + file_id |
| UT-TASK-007 | SR 첨부파일 경로 순회 방지 | 400 Bad Request |
| UT-TASK-008 | 고객(CUSTOMER) SR 자기 것만 조회 | 200 + 본인 SR만 |
| UT-TASK-009 | SR 검색 (제목 키워드) | 200 + 필터 결과 |
| UT-TASK-010 | SR 만족도 평가 | 200 + rating 저장 |
### 4.4 SSL 관리 (ssl_manager) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-SSL-001 | SSL 도메인 등록 | 201 + ssl_id |
| UT-SSL-002 | 중복 도메인 등록 | 409 Conflict |
| UT-SSL-003 | SSL 즉시 점검 — 정상 응답 파싱 | 200 + days_left 계산 |
| UT-SSL-004 | SSL 즉시 점검 — SSH 실패 시 | 200 + error_msg 기록 |
| UT-SSL-005 | 만료 임박 알림 등급 (EXPIRED ≤0) | level=EXPIRED |
| UT-SSL-006 | 만료 임박 알림 등급 (URGENT ≤7) | level=URGENT |
| UT-SSL-007 | 만료 임박 알림 등급 (WARN ≤30) | level=WARN |
| UT-SSL-008 | 정상 인증서 (>30일) | level=OK |
| UT-SSL-009 | SSL 수동 갱신 완료 기록 | 200 + renewed_at 업데이트 |
| UT-SSL-010 | SSL 도메인 삭제 | 204 No Content |
### 4.5 PM 정기점검 (pm) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-PM-001 | PM 템플릿 생성 | 201 + template_id |
| UT-PM-002 | PM 템플릿 목록 조회 | 200 + 카테고리별 목록 |
| UT-PM-003 | PM 스케줄 생성 (MONTHLY) | 201 + next_scheduled 계산 |
| UT-PM-004 | PM 스케줄 생성 (WEEKLY) | 201 + 7일 후 next_scheduled |
| UT-PM-005 | PM 스케줄 생성 (QUARTERLY) | 201 + 90일 후 next_scheduled |
| UT-PM-006 | PM 작업 생성 (WorkTimetable 연동) | 201 + timetable_id |
| UT-PM-007 | PM 결과 저장 — PASS | 200 + result=PASS |
| UT-PM-008 | PM 결과 저장 — FAIL (비고 필수) | 400 if note 없음 |
| UT-PM-009 | PM 완료 처리 | 200 + completed_at 기록 |
| UT-PM-010 | PM Excel 보고서 다운로드 | 200 + Content-Type: xlsx |
| UT-PM-011 | next_scheduled 계산 — MONTHLY 말일 | 말일 처리 정확성 |
| UT-PM-012 | PM 템플릿 소프트 삭제 | 200 + is_active=False |
### 4.6 장애 관리 (incidents) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-INC-001 | 장애 생성 (P1) | 201 + INC-YYYYMMDD-XXXXXX 형식 |
| UT-INC-002 | 장애 생성 (P4) | 201 + 알림 없음 |
| UT-INC-003 | P1/P2 생성 → Messenger 알림 | 알림 함수 호출 확인 (mock) |
| UT-INC-004 | 상태 전환 OPEN→INVESTIGATING | 200 + 타임라인 기록 |
| UT-INC-005 | 잘못된 상태 전환 CLOSED→OPEN | 400 Bad Request |
| UT-INC-006 | 장애 타임라인 조회 | 200 + events 목록 |
| UT-INC-007 | 장애 종결 (RCA 필수) | 400 if rca 없음 |
| UT-INC-008 | 장애 목록 — P1 필터 | 200 + P1 only |
| UT-INC-009 | 장애 통계 (기간별) | 200 + count by priority |
| UT-INC-010 | 장애 SR 연동 | 200 + related_sr_ids 업데이트 |
### 4.7 온콜/당직 (oncall) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-OC-001 | 당직 단건 등록 | 201 + duty_id |
| UT-OC-002 | 중복 당직 등록 (같은 날+교대) | 409 Conflict |
| UT-OC-003 | 당직 일괄 등록 (최대 62건) | 201 + count |
| UT-OC-004 | 당직 일괄 — 초과 (63건) | 422 Validation Error |
| UT-OC-005 | 오늘 당직 조회 | 200 + 교대별 그룹 |
| UT-OC-006 | 월별 당직 조회 | 200 + 해당 월 목록 |
| UT-OC-007 | 당직 삭제 | 204 No Content |
### 4.8 배치 작업 (batch) 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-BAT-001 | 배치 작업 생성 | 201 + batch_id |
| UT-BAT-002 | 위험 명령 차단 (rm -rf /) | 400 Bad Request |
| UT-BAT-003 | 위험 명령 차단 (shutdown) | 400 Bad Request |
| UT-BAT-004 | 위험 명령 차단 (fork bomb) | 400 Bad Request |
| UT-BAT-005 | 배치 수동 실행 요청 | 202 Accepted |
| UT-BAT-006 | 배치 실행 이력 조회 | 200 + runs 목록 |
| UT-BAT-007 | 배치 실패 시 SR 자동 생성 | SR 생성 확인 (mock) |
| UT-BAT-008 | 비활성 배치 스케줄 — 실행 안 함 | is_active=False 체크 |
| UT-BAT-009 | 배치 작업 삭제 | 204 No Content |
| UT-BAT-010 | TIMEOUT 처리 (asyncio timeout) | 실행 상태=TIMEOUT |
### 4.9 암호화 유틸 단위 테스트
| 테스트 ID | 테스트명 | 기대 결과 |
|-----------|----------|-----------|
| UT-CRYPTO-001 | AES-256-GCM 암호화/복호화 왕복 | 원문 복원 성공 |
| UT-CRYPTO-002 | 서로 다른 평문 → 다른 암호문 | 결정론적 아님 확인 |
| UT-CRYPTO-003 | 잘못된 키로 복호화 | 예외 발생 |
| UT-CRYPTO-004 | 빈 문자열 암호화 | 정상 처리 |
| UT-CRYPTO-005 | 한국어 포함 문자열 암호화 | UTF-8 왕복 성공 |
### 4.10 스케줄러 단위 테스트
```python
# tests/unit/test_scheduler.py
import pytest
from datetime import datetime
from freezegun import freeze_time
from core.scheduler import _calc_next
from models import PmSchedule, PmFrequency
@pytest.mark.asyncio
async def test_calc_next_weekly():
with freeze_time("2026-01-01"):
sched = PmSchedule(frequency=PmFrequency.WEEKLY)
result = _calc_next(sched, datetime(2026, 1, 1))
assert result == datetime(2026, 1, 8)
@pytest.mark.asyncio
async def test_calc_next_monthly_end_of_month():
# 1월 31일에서 +1달 → 2월 28일 (말일 처리)
sched = PmSchedule(frequency=PmFrequency.MONTHLY, day_of_month=31)
result = _calc_next(sched, datetime(2026, 1, 31))
assert result.day == 28 # 2026년 2월 말일
```
---
## 5. 통합 테스트 계획
### 5.1 SR 처리 전체 워크플로우
**시나리오**: 고객 SR 접수 → 담당자 배정 → 처리 → 완료 → 만족도 평가
```
TC-INT-SR-001: SR 접수부터 완료까지 전체 흐름
1. POST /tasks/ — SR 생성 (CUSTOMER 역할)
2. GET /tasks/{id} — 생성 확인
3. PATCH /assign/{sr_id} — 담당자 배정 (PM 역할)
4. PATCH /tasks/{id}/status — IN_PROGRESS 전환
5. POST /work/ — 처리 내역 등록
6. PATCH /tasks/{id}/status — RESOLVED 전환
7. POST /rating/ — 만족도 5점 등록
8. GET /dashboard/summary — 통계 반영 확인
기대 결과: 전 단계 성공, 최종 SR 상태=RESOLVED, rating=5
```
### 5.2 결재 워크플로우
**시나리오**: CHANGE 유형 SR → 결재 요청 → 승인 → 실행
```
TC-INT-APV-001: 결재 승인 워크플로우
1. POST /tasks/ — CHANGE SR 생성
2. POST /approvals/ — 결재 요청 (결재자 2단계 설정)
3. PATCH /approvals/{id}/approve — 1단계 승인
4. PATCH /approvals/{id}/approve — 2단계 승인
5. GET /tasks/{sr_id} — SR 상태 = APPROVED 확인
6. PATCH /tasks/{id}/status — IMPLEMENTING 전환
TC-INT-APV-002: 결재 거부 워크플로우
1. POST /tasks/ + POST /approvals/
2. PATCH /approvals/{id}/reject — 거부 (사유 필수)
3. GET /tasks/{sr_id} — SR 상태 = REJECTED 확인
```
### 5.3 PM 정기점검 워크플로우
```
TC-INT-PM-001: PM 스케줄 → 자동 작업 생성
1. POST /pm/templates/ — 체크리스트 템플릿 생성
2. POST /pm/schedules/ — MONTHLY 스케줄 등록
3. (스케줄러 _auto_generate_pm 함수 직접 호출)
4. GET /timetable/ — WorkTimetable 생성 확인
5. GET /pm/works/{id} — PM 작업 목록 확인
TC-INT-PM-002: PM 결과 저장 및 Excel 보고서
1. (PM 작업 생성 선행)
2. POST /pm/works/{id}/results — 각 항목 PASS/FAIL 저장
3. PATCH /pm/works/{id}/complete — 완료 처리
4. GET /pm/works/{id}/report — Excel 다운로드
5. openpyxl로 파일 열기 → PASS/FAIL 색상 확인
```
### 5.4 장애 처리 워크플로우
```
TC-INT-INC-001: P1 장애 발생 → 처리 → 종결
1. POST /incidents/ — P1 장애 등록
→ Messenger 알림 mock 확인
2. POST /incidents/{id}/timeline — "장애 감지 완료" 기록
3. PATCH /incidents/{id}/status — INVESTIGATING
4. PATCH /incidents/{id}/status — MITIGATED (조치 내역 포함)
5. PATCH /incidents/{id}/status — RESOLVED (임시 해결)
6. POST /incidents/{id}/close — RCA 문서 포함 종결
7. GET /incidents/{id} — 전체 타임라인 확인
```
### 5.5 배치 실행 및 실패 알림
```
TC-INT-BAT-001: 배치 실행 실패 → SR 자동 생성
1. POST /batch/jobs — 의도적 실패 명령으로 배치 등록
(예: "exit 1" 명령)
2. POST /batch/jobs/{id}/run — 수동 실행
3. (BackgroundTask 완료 대기)
4. GET /batch/jobs/{id}/runs — 상태 = FAILED 확인
5. GET /tasks/ — 자동 생성된 SR 확인 (sr_type=LOG, priority=HIGH)
```
### 5.6 Messenger 알림 통합 테스트
```
TC-INT-MSG-001: ITSM 이벤트 → Messenger 채널 발송
1. mock Messenger API (respx)
2. P1 장애 생성 → /incidents/ POST
3. respx 캡처된 요청에서 채널 ID, 메시지 내용 검증
4. 메시지에 incident_id, priority, title 포함 확인
5. 서버 IP/비밀번호 미포함 확인 (보안)
TC-INT-MSG-002: Bot 명령 처리
1. POST /messenger/webhook — "/itsm sr list" 명령
2. 응답 메시지에 SR 목록 포함 확인
3. POST /messenger/webhook — "/itsm help"
4. 응답 메시지에 명령어 목록 확인
```
---
## 6. 비기능 테스트 계획
### 6.1 성능 테스트
| 항목 | 목표 | 측정 방법 |
|------|------|-----------|
| API 응답 시간 (평균) | ≤ 500ms | locust or k6 |
| API 응답 시간 (P99) | ≤ 2000ms | locust or k6 |
| 동시 사용자 | 50명 이상 정상 처리 | locust 동시 접속 |
| DB 트랜잭션 | 100 TPS 이상 | pytest-benchmark |
| 파일 업로드 | 10MB 이하 ≤ 3초 | httpx 직접 테스트 |
### 6.2 보안 테스트
| 항목 | 테스트 방법 | 기대 결과 |
|------|------------|-----------|
| SQL 인젝션 | 검색 파라미터에 SQL 구문 주입 | 에러 없이 빈 결과 |
| XSS | SR 제목에 `<script>alert(1)</script>` | HTML 이스케이프 |
| JWT 위조 | 임의 서명 토큰 사용 | 401 |
| 경로 순회 | `../../../etc/passwd` 첨부파일 | 400 |
| SSH 명령 인젝션 | `; rm -rf /` 포함 명령 | 400 |
| 서버 정보 노출 | API 응답에 IP/PW 포함 여부 | 미포함 확인 |
| 스택트레이스 노출 | 의도적 오류 발생 | SR ID + 요약만 반환 |
### 6.3 감사 로그 무결성 테스트
```
TC-AUDIT-001: 해시 체인 무결성
1. 여러 감사 로그 생성 (API 호출 10회)
2. GET /audit/logs — 전체 조회
3. 각 로그의 prev_hash → 이전 로그 hash 일치 확인
4. DB에서 중간 로그 직접 수정
5. GET /audit/verify — 무결성 깨짐 감지 확인
```
---
## 7. 테스트 케이스 목록 요약
| 모듈 | 단위 TC | 통합 TC | 합계 |
|------|---------|---------|------|
| auth | 8 | 2 | 10 |
| tasks/SR | 10 | 4 | 14 |
| approvals | 6 | 3 | 9 |
| ssl_manager | 10 | 2 | 12 |
| pm | 12 | 3 | 15 |
| incidents | 10 | 2 | 12 |
| oncall | 7 | 1 | 8 |
| batch | 10 | 2 | 12 |
| scheduler | 6 | 2 | 8 |
| crypto/security | 5 | 3 | 8 |
| messenger | 4 | 3 | 7 |
| audit | 4 | 2 | 6 |
| **합계** | **92** | **29** | **121** |
---
## 8. 결함 관리
### 8.1 결함 등급
| 등급 | 정의 | 처리 기한 |
|------|------|-----------|
| Critical | 시스템 중단, 데이터 손실, 보안 취약점 | 즉시 (24시간 내) |
| Major | 핵심 기능 비정상, 결과 오류 | 3일 내 |
| Minor | 비핵심 기능 문제, UI 오류 | 7일 내 |
| Trivial | 오타, 경미한 표시 오류 | 다음 버전 |
### 8.2 결함 생명주기
```
NEW → ASSIGNED → IN_PROGRESS → FIXED → VERIFIED → CLOSED
REOPENED (재현 시)
```
### 8.3 결함 보고서 양식
```
결함 ID: BUG-YYYY-NNN
제목: [모듈] 결함 요약
심각도: Critical/Major/Minor/Trivial
재현 단계:
1. ...
2. ...
실제 결과: ...
기대 결과: ...
스크린샷/로그: (첨부)
발견일: YYYY-MM-DD
발견자: ...
```
---
## 9. 완료 기준
### 9.1 단계별 완료 기준
**단위 테스트 완료**:
- [ ] 모든 단위 TC 실행 완료
- [ ] 코드 커버리지 80% 이상
- [ ] Critical/Major 결함 0건
**통합 테스트 완료**:
- [ ] 모든 통합 시나리오 TC 실행 완료
- [ ] 주요 워크플로우 E2E 검증 완료
- [ ] Critical/Major 결함 0건
**보안 테스트 완료**:
- [ ] 보안 TC 전 항목 통과
- [ ] API 응답에 민감 정보 미포함 확인
- [ ] 감사 로그 무결성 확인
### 9.2 테스트 실행 명령
```bash
# 전체 단위 테스트
cd C:\GUARDiA\itsm
pytest tests/unit/ -v --cov=. --cov-report=html
# 통합 테스트
pytest tests/integration/ -v --timeout=30
# 특정 모듈
pytest tests/unit/test_incidents.py -v
# 커버리지 HTML 보고서 확인
open htmlcov/index.html
```
---
*본 테스트 계획서는 GUARDiA ITSM v1.0 기준으로 작성되었으며, 버전 업그레이드 시 갱신이 필요합니다.*