zioinfo-mail/manual/02_단위통합테스트계획서.md
DESKTOP-TKLFCPR\ython e228faabf5 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

20 KiB

GUARDiA ITSM + Messenger — 단위·통합 테스트 계획서

문서 버전: 1.0
작성일: 2026-05-25
대상 시스템: GUARDiA ITSM v1.0, GUARDiA Messenger v1.0


목차

  1. 개요
  2. 테스트 범위 및 전략
  3. 테스트 환경
  4. 단위 테스트 계획
  5. 통합 테스트 계획
  6. 비기능 테스트 계획
  7. 테스트 케이스 목록
  8. 결함 관리
  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 공통 픽스처

# 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
# 예시 테스트 코드
@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 스케줄러 단위 테스트

# 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 테스트 실행 명령

# 전체 단위 테스트
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 기준으로 작성되었으며, 버전 업그레이드 시 갱신이 필요합니다.