405. 시스템 테스트 (System Test)
⚠️ 이 문서는 단위 테스트와 통합 테스트를 거쳐 완성된 '소프트웨어 덩어리'를 실제 운영될 하드웨어와 네트워크 환경(완전한 시스템) 위에 올려놓고, 기능적인 요구사항뿐만 아니라 성능, 보안, 회복성 같은 '비기능적 요구사항'까지 혹독하게 검증하는 시스템 테스트를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 시스템 테스트는 소프트웨어가 '코드'의 세계를 벗어나, 실제 운영체제, DB, 서버 하드웨어 등 다른 이기종 구성요소들과 결합된 **'거대한 전체 시스템(Whole System)'**으로서 제대로 돌아가는지 확인하는 종합 검진이다.
- 가치: 코드의 논리적 버그(기능)를 잡는 것을 넘어, "동시 접속자 1만 명이 들어왔을 때 서버가 뻗지 않는가(성능)", "해커의 공격을 막아내는가(보안)" 등 **비기능적 요구사항(NFR)**을 증명하는 유일한 단계다.
- 기술 체계: 내부 코드를 모르는 상태에서 외부 스펙 명세서(SRS)만을 보고 검증하는 블랙박스 테스트(Black-box Testing) 기법이 주로 사용되며, 개발팀 내부의 전담 QA(Quality Assurance) 조직이 주도한다.
Ⅰ. 개요: 온전한 형태를 갖추다 (Context & Necessity)
단위 테스트가 '엔진'을 깎는 것이고 통합 테스트가 '엔진과 바퀴'를 연결하는 것이라면, **시스템 테스트(System Test)**는 완성된 자동차를 테스트 트랙에 올리고 시속 200km로 밟아보는 과정이다.
지금까지 개발자들은 각자의 노트북(로컬 환경)이나 가짜 객체(Mock) 위에서 코드를 돌려보며 "내 코드는 완벽해!"라고 외쳤다. 하지만 진짜 리눅스 서버에 올리고, 진짜 오라클 DB와 연동하고, 진짜 인터넷 망을 타는 순간 예상치 못한 일들이 터진다.
- "로컬에서는 로그인 버튼 누르면 0.1초 만에 넘어갔는데, 실서버에선 3초나 걸리네요?" (성능 문제)
- "비밀번호에 특수문자 넣었더니 DB가 터졌어요!" (보안 문제)
이처럼 '기능'은 맞지만 '현실의 물리적 제약' 때문에 발생하는 치명적인 결함들을 찾아내기 위해, 실제 고객에게 인도하기 직전에 **실제 운영 환경과 100% 동일하게 세팅된 환경(Staging Environment)**에서 수행하는 테스트가 바로 시스템 테스트다.
📢 섹션 요약 비유: 우주선을 공장에서 아무리 튼튼하게 조립(통합 테스트)했어도, 진짜 우주로 쏘아 올리기 전에 무중력 방과 진공 챔버(실제 환경) 안에 우주선을 통째로 집어넣고 극한의 압력과 추위를 견디는지 혹독하게 테스트하는 것과 같습니다.
Ⅱ. 시스템 테스트의 양대 산맥: 기능 vs 비기능
시스템 테스트는 크게 두 가지 영역으로 나뉜다. 이 중에서도 **'비기능 테스트'**의 비중이 압도적으로 높다.
1. 기능 테스트 (Functional Testing)
- 목적: 요구사항 명세서(SRS)에 적힌 '기능'들이 시스템 단위에서 유기적으로 잘 작동하는가?
- 특징: 개발자가 아니라 테스트 전문 인력(QA)이 사용자의 관점에서 블랙박스 테스트를 진행한다. "버튼을 누르면 창이 닫힌다" 같은 비즈니스 로직의 결함을 찾는다.
2. 비기능 테스트 (Non-Functional Testing) ★
시스템 테스트의 꽃이다. 아무리 기능이 완벽해도 비기능 테스트를 통과 못 하면 제품을 팔 수 없다.
- 성능 테스트 (Performance Test): 부하(Load), 스트레스(Stress), 스파이크(Spike) 테스트. 동접자가 몰렸을 때 응답 시간이 3초 이내인지 측정한다. (도구: JMeter, LoadRunner)
- 보안/침투 테스트 (Security/Penetration Test): SQL 인젝션이나 XSS 공격을 날려 서버가 뚫리는지 확인한다.
- 회복 테스트 (Recovery Test): 서버 전원 플러그를 확 뽑아버리거나 네트워크 선을 가위로 잘랐을 때, 시스템이 데이터를 날리지 않고 5분 내에 스스로 정상 복구되는지 깡패같이 테스트한다.
- 사용성 테스트 (Usability Test): 버튼 위치나 색깔이 사용자에게 직관적이고 편안한지 평가한다.
┌───────────────────────────────────────────────────────────────────┐
│ V-모델 관점에서의 시스템 테스트 포지셔닝 시각화 │
├───────────────────────────────────────────────────────────────────┤
│ │
│ [요구사항 분석] ──────────────────────────▶ [인수 테스트] (고객) │
│ ▼ ▲ │
│ [기본 설계] ────────────────────────▶ 👑 [시스템 테스트] (QA) │
│ ▼ ▲ (비기능 집중 검증) │
│ [상세 설계] ────────────────────▶ [통합 테스트] (개발자) │
│ ▼ ▲ │
│ [코딩] ───────────────▶ [단위 테스트] (개발자) │
│ │
│ ★ 시스템 테스트는 '기본 설계(System Design)' 단계에서 정의된 │
│ 전체 시스템 아키텍처와 성능 목표를 달성했는지 증명하는 단계다. │
└───────────────────────────────────────────────────────────────────┘
Ⅲ. 환경 구축의 딜레마 (Staging Environment)
시스템 테스트가 성공하려면 테스트 환경이 '진짜 상용(Production) 환경'과 100% 쌍둥이처럼 똑같아야 한다. 이를 **스테이징 환경(Staging)**이라고 부른다.
- 어려움: 실서버가 CPU 64코어에 256GB 램을 쓰는 수백 대짜리 클러스터라면, 테스트 환경도 똑같이 만들어야 한다. 이 인프라 비용만 수십억 원이 깨진다.
- 해결책: 과거엔 돈이 없어서 테스트 환경을 실서버의 1/10 크기로 만들고 대충 곱하기 10을 해서 성능을 유추했다 (매우 부정확). 하지만 현대에는 **클라우드(AWS, GCP)**와 테라폼(Terraform) 같은 IaC(Infrastructure as Code) 기술 덕분에, 테스트할 때만 잠깐 수백 대의 서버를 복사본으로 찍어내어 테스트하고 즉시 삭제함으로써 100% 동일한 환경에서의 시스템 테스트가 가능해졌다.
Ⅳ. 결론
"소프트웨어는 코드가 아니라 물리적 현실 위에 존재한다." 시스템 테스트는 코드 블록의 집합체를 비로소 현실 세계의 거친 물리 법칙(메모리 한계, 네트워크 지연, 서버 다운)과 조우하게 만드는 과정이다. 단위/통합 테스트가 개발자의 '논리적 자부심'을 확인하는 자리라면, 시스템 테스트는 그 자부심이 냉혹한 '물리적 한계' 앞에서도 무너지지 않음을 증명하는 진실의 방이다. 성능과 복원력이라는 비기능적 품질은 이 단계를 거치지 않고서는 절대 확보할 수 없다.
📌 관련 개념 맵
- 전제되는 테스트: 통합 테스트 (Integration Test)
- 다음 단계 테스트: 인수 테스트 (Acceptance Test)
- 테스트 기법: 블랙박스 테스트 (Black-box Testing)
- 주요 비기능 테스트: 성능 부하(Load), 스트레스(Stress), 회복(Recovery), 보안(Security)
👶 어린이를 위한 3줄 비유 설명
- 자동차 공장에서 바퀴도 잘 굴러가고(단위 테스트), 바퀴와 엔진 조립도 튼튼하게(통합 테스트) 마쳤어요.
- 이제 이 완성된 자동차를 실제 사막의 모래폭풍 속이나, 꽁꽁 언 얼음길 위에 직접 올려놓고 시속 200km로 쌩쌩 달려보는 거예요.
- 이렇게 "진짜 험난한 현실 세상에서도 자동차가 고장 나지 않고 잘 버티는지" 전체적으로 빡세게 검사하는 것을 시스템 테스트라고 한답니다!