개념
성적서가 주장하는 것은 결과가 아니라 재현 가능성이다
성적서에 "평균 응답시간 1.2초 — 적합"이라고 적혀 있다고 하자. 이 문장이 무엇을 주장하는가? 흔한 오해는 "이 제품은 1.2초에 응답한다"는 주장으로 읽는 것이다. 그렇지 않다.
성적서가 실제로 주장하는 것은 이것이다.
명시된 환경에서, 명시된 방법으로, 명시된 시점에 측정했을 때 1.2초였고, 같은 조건을 갖추면 누구든 비슷한 값을 얻을 수 있다.
앞쪽 세 개의 "명시된"이 없으면 뒤쪽 주장이 성립하지 않는다. 환경 기재가 부실한 성적서는 숫자가 아무리 정확해도 검증 불가능한 주장 이 된다. 그리고 검증할 수 없는 문서는 분쟁에서 힘을 잃는다.
ISO/IEC 17025가 기술 기록(technical records, 7.5)에 요구하는 문장이 정확히 이 지점을 겨냥한다. 기록은 결과에 영향을 준 요소를 식별할 수 있고, 비교 가능한 조건에서 활동을 반복할 수 있을 만큼의 정보 를 담아야 한다. "반복할 수 있을 만큼"이 기준이다. 예뻐 보이는 만큼이 아니다.
소프트웨어 시험에서 환경이 결과를 뒤집는 방식
물리 시험에서는 온도·습도·기압이 환경이다. 소프트웨어 시험에서는 그 자리를 다른 것들이 차지하는데, 영향의 크기는 오히려 더 크다. 같은 빌드를 같은 스크립트로 돌려도 다음 중 하나만 달라지면 결과가 바뀐다.
| 요소 | 결과가 바뀌는 방식 |
|---|---|
| CPU 코어 수 | 스레드 풀 크기가 자동 산정되는 프레임워크에서 처리량이 배로 갈린다 |
| JVM 힙 크기 | GC 주기가 달라져 응답시간 꼬리(tail)가 완전히 달라진다 |
| DB의 데이터 양 | 인덱스 없이 100건은 빠르고 100만 건은 느리다 |
| 부하 생성기 위치 | 같은 리전이면 RTT 1ms, 다른 대륙이면 200ms |
| 캐시 예열 여부 | 첫 1분과 그 이후가 다른 제품이 된다 |
| 동시에 돌아간 다른 작업 | 배치 잡 하나가 같은 DB를 긁고 있으면 숫자가 무너진다 |
여기서 특히 성적서 실무자가 자주 놓치는 것이 마지막 줄이다. 공유 환경에서 측정한 결과는 그 사실을 밝히지 않으면 재현 불가능하다. "스테이징 서버"라고만 적힌 성적서는 그 서버에 그때 무엇이 같이 돌고 있었는지 영영 알 수 없게 만든다.
다섯 축으로 적는다
환경 기재를 체계 없이 하면 매번 빠지는 항목이 생긴다. 다섯 축으로 나눠 훑으면 누락이 크게 준다.
1. 하드웨어·인프라
시험 대상 서버
- AWS EC2 c6i.2xlarge (vCPU 8, 메모리 16GB)
- 리전 ap-northeast-2 (서울), 단일 인스턴스(이중화 없음)
- 스토리지 gp3 100GB, IOPS 3000
DB 서버
- RDS PostgreSQL 15.5, db.m6g.large, 단일 AZ
부하 생성기
- EC2 c6i.xlarge 2대, 같은 리전·같은 VPC클라우드라면 인스턴스 타입까지 적는다. "8코어 16GB"보다 c6i.2xlarge가
낫다 — 타입 하나에 세대·클럭·네트워크 대역폭이 함께 묶여 있기 때문이다.
단일 인스턴스인지 이중화인지 는 반드시 적는다. 성능 수치의 의미가
완전히 달라진다.
2. 소프트웨어 스택
OS Ubuntu 22.04.4 LTS (kernel 5.15.0-107)
런타임 OpenJDK 21.0.3 (Temurin), -Xms4g -Xmx4g -XX:+UseG1GC
WAS Spring Boot 3.3.2 / 내장 Tomcat 10.1, 스레드 최대 200
DB PostgreSQL 15.5, shared_buffers 4GB, max_connections 200
대상 제품 OO페이 서버 2.1.4 (빌드 2026-08-30, 커밋 a3f91c2)여기서 핵심은 기본값이 아닌 설정을 적는 것 이다. 전부 적을 필요는 없고, 성능·동작에 영향을 주는 튜닝 값만 적으면 된다. 힙 크기, 커넥션 풀, 스레드 수, 타임아웃. 이 네 가지는 소프트웨어 성능 시험에서 거의 항상 영향을 준다.
3. 네트워크 구성
부하 생성기 → 대상 서버 동일 VPC 내부, 평균 RTT 0.4ms
대상 서버 → DB 동일 서브넷, 평균 RTT 0.3ms
외부 PG 연동 [제외 범위] 목(mock) 서버로 대체, 고정 지연 50ms
TLS TLS 1.3, 대상 서버에서 종료(termination)목이나 스텁으로 대체한 구간은 반드시 밝힌다. 외부 결제 PG를 목으로 바꿔놓고 그 사실을 안 적으면, 그 성적서의 응답시간은 실제 서비스와 무관한 숫자가 된다. 대체했다는 사실 자체는 문제가 아니다 — 레슨 1의 제외 범위에 근거가 있으면 정당한 설계다. 문제는 감추는 것이다.
4. 데이터
가장 자주 빠지고, 성능 시험에서 가장 큰 차이를 만드는 축이다.
사전 적재 데이터 회원 100만 건, 거래 이력 5,000만 건 (2026-01~08 분포 모사)
시험용 계정 전용 계정 2,000개, 각 계정 잔액 사전 충전
캐시 상태 측정 전 5분 예열(warm-up) 수행, 예열 구간은 집계 제외
초기화 각 회차 시작 전 DB 스냅샷 복원"거래 이력 5,000만 건"과 "거래 이력 1,000건"은 같은 쿼리에 대해 다른 제품이다. 데이터 규모를 안 적은 성능 성적서는 사실상 아무것도 증명하지 못한다.
5. 시점과 기간
시험 수행 2026-09-05 10:00 ~ 2026-09-05 18:30 (KST)
측정 구간 각 시나리오당 30분 정상 상태(steady state), 예열 5분 제외
반복 시나리오별 3회 반복, 3회 값 모두 성적서에 기재
공유 자원 시험 시간대에 동일 계정의 배치 작업 중지 확인마지막 줄 같은 문장이 성적서에 들어가 있으면, 읽는 사람은 그 시험이 통제된 조건에서 수행됐다고 판단한다. 한 줄로 문서의 신뢰도가 올라간다.
버전은 "최신" 이 아니라 숫자로 적는다
환경 기재에서 가장 조용한 실패는 버전 칸에 "최신" 이라고 쓰는 것이다. 쓸 때는 정확한 말처럼 느껴지지만, 시간이 지나면 무엇인지 알 수 없는 값이 된다. 성적서는 발행 후 몇 년을 읽히는 문서이므로, 읽히는 시점에는 그 칸이 비어 있는 것과 같아진다.
같은 성격의 표현이 생각보다 많다.
| 쓰면 안 되는 표기 | 왜 재현이 안 되나 | 대신 적을 것 |
|---|---|---|
| 최신 버전 / latest | 읽는 시점마다 가리키는 대상이 달라진다 | Chrome 129.0.6668.59 |
| Windows 11 | 빌드마다 스케줄러·네트워크 스택이 다르다 | Windows 11 23H2 (22631.4169) |
| Java 21 | 패치 버전에 따라 GC 동작이 바뀐다 | OpenJDK 21.0.3+9 (Temurin) |
| 운영과 동일 | 운영 구성도 계속 변한다 | 그 시점 구성을 숫자로 전개 |
| v2.1 | 같은 태그로 여러 번 빌드된다 | 2.1.4 (빌드 2026-08-30, 커밋 a3f91c2) |
마지막 줄이 소프트웨어 시험의 고유 문제다. 버전 번호는 사람이 붙이고
빌드는 기계가 만든다. 같은 2.1.4 라도 금요일 빌드와 월요일 빌드가
다를 수 있으므로, 성적서에는 버전·빌드 일시·커밋 해시 세 개 를 함께
적는다. 셋 중 하나만 살아남아도 대상을 특정할 수 있다.
컨테이너라면 태그보다 다이제스트 가 답이다. myapp:2.1.4 는 같은
이름으로 다시 푸시될 수 있지만 다이제스트는 바뀌지 않는다.
대상 이미지 opay-api:2.1.4 / sha256:9f2c1b7a3e5d4f80...
빌드 2026-08-30 13:22 KST / 커밋 a3f91c2클라우드가 만든 새로운 문제 — 환경이 고정되지 않는다
전통적인 시험 환경 기재는 "고정된 장비"를 전제한다. 클라우드는 그 전제를 깨뜨린다. 오토스케일이 걸린 환경에서는 측정 도중에 환경 자체가 변한다.
이때 선택지는 둘이다.
| 선택 | 무엇을 적는가 | 언제 쓰는가 |
|---|---|---|
| 스케일 고정 | 인스턴스 수를 고정하고 그 수를 기재 | 단위 성능·용량 산정이 목적일 때 |
| 스케일 활성 | 스케일 정책(임계값·쿨다운·최대 대수)과 측정 중 실제 인스턴스 변화 이력을 기재 | 실제 운영 형태의 처리 능력을 증명할 때 |
둘 다 정당하지만 섞으면 안 된다. 그리고 어느 쪽인지 성적서에 명시하지 않으면 읽는 사람이 숫자를 잘못 해석한다. 스케일이 열려 있는 상태에서 잰 처리량을 "서버 1대의 처리량"으로 읽으면 용량 산정이 통째로 틀어진다.
컨테이너 환경도 같은 문제를 만든다. Kubernetes에서 파드의 CPU 제한(limit)과 요청(request)이 다르면, 노드 여유 상황에 따라 같은 파드가 다른 성능을 낸다. 이럴 때는 limit·request 값과 노드 스펙을 함께 적어야 재현 가능성이 생긴다.
어디까지 적을 것인가 — 과잉 기재의 함정
"전부 적으면 되는 것 아닌가"라고 생각할 수 있는데, 실제로는 과잉도 문제다. 서버 설정을 통째로 붙여넣은 성적서는 읽히지 않고, 읽히지 않는 정보는 없는 것과 같다. 판단 기준은 하나다.
이 값이 달랐다면 결과가 달라졌을까?
그렇다 → 본문에 적는다 아마도 → 부록에 적는다 아니다 → 적지 않는다
그리고 부록을 적극적으로 쓴다. 본문에는 판단에 필요한 10~20줄, 부록에는 전체 설정 덤프와 스크립트. ISO/IEC 17025도 성적서 본문을 간결하게 (clear, concise and accurate) 낼 것을 요구하면서, 동시에 보고하지 않은 정보는 언제든 제공 가능한 상태로 보유 할 것을 요구한다. 본문에서 빼는 것과 기록에서 빼는 것은 전혀 다른 일이다.
항목별 민감도 — 같은 기준을 일률로 적용하지 않는다
앞의 기준은 좋지만 매번 처음부터 따지면 느리다. 항목마다 결과를 바꾸는 힘의 크기가 대체로 정해져 있으므로, 등급을 미리 붙여 두면 판단이 빨라진다.
| 항목 | 결과를 바꾸는 힘 | 기재 위치 |
|---|---|---|
| 데이터 규모와 분포 | 매우 크다 — 쿼리 계획 자체가 바뀐다 | 본문 필수 |
| 동시 사용자 수·부하 모델 | 매우 크다 — 측정의 정의에 가깝다 | 본문 필수 |
| 대상 빌드 식별자 | 결과가 아니라 대상 을 바꾼다 | 본문 필수 |
| CPU·메모리, 인스턴스 타입 | 크다 | 본문 필수 |
| 런타임 버전과 힙·풀·타임아웃 | 크다 | 본문 필수 |
| 브라우저·단말 모델, 측정 도구 | 클라이언트에서 쟀다면 크다 | 측정 지점에 따라 본문 |
| OS 패치 수준 | 보통 — 커널 설정이 걸릴 때만 | 부록 |
| 서버 호스트명·사설 IP | 거의 없다 | 적지 않는다 |
| 설치 디렉터리 경로 | 없다 | 적지 않는다 |
위 다섯 줄은 빠지면 성적서가 성립하지 않는 축 이고, 맨 아래 두 줄은 재현에 도움이 안 되면서 내부 구성 노출만 늘린다. 판단의 대상은 가운데 영역이고, 그때 묻는 질문은 "이 시험이 무엇에 걸려 있는가"다.
여섯 번째 줄의 측정 도구 가 특히 자주 빠진다. 도구가 올라가면서 지표 계산식이 바뀌어 같은 제품의 점수가 떨어지는 일이 있다. 도구 버전이 없는 성적서는 그때 제품이 나빠진 것인지 측정 기준이 바뀐 것인지 구분할 수 없다.
환경 기재를 자동화하는 실무 기법
손으로 적으면 반드시 틀린다. 사람이 적은 "메모리 16GB"가 실제로는 15.6GB인 일은 흔하다. 성적서 실무가 성숙한 조직은 환경 정보를 시험 시작 시점에 스크립트로 수집 한다.
# 환경 스냅샷 수집 예 — 시험 시작 직전에 실행해 산출물로 보관한다
{
echo "## 수집 시각"; date -Is
echo "## 커널·OS"; uname -a; cat /etc/os-release | head -2
echo "## CPU·메모리"; nproc; free -g
echo "## 런타임"; java -version 2>&1
echo "## 대상 빌드"; curl -s localhost:8080/actuator/info
echo "## DB 설정"; psql -c "show shared_buffers; show max_connections;"
} > env-snapshot-$(date +%Y%m%d-%H%M).txt이렇게 남긴 파일은 두 가지 역할을 한다. 성적서 환경 절의 원천이 되고, 나중에 "그때 설정이 뭐였냐"는 질문에 대한 답이 된다. 재현성은 의지가 아니라 절차로 확보된다.
측정 결과와 환경을 한 묶음으로 보관한다
환경 스냅샷을 잘 남겨도 결과 파일과 따로 놓이면 쓸 수 없다. 석 달 뒤 "이 그래프는 어느 환경에서 나온 것인가"를 복원할 수 없으면 그 환경 정보는 없는 것과 같다. 그래서 묶는 단위를 회차(run) 로 잡는다.
runs/
20260905-1000_r1_scenario-A/
env-snapshot.txt ← 시작 직전 자동 수집
k6-summary.json ← 결과 원본
server-metrics.csv ← 자원 사용률
20260905-1130_r2_scenario-A/
report/
environment-section.md ← 성적서 본문에 들어간 10~20줄
run-index.csv ← 성적서 표의 어느 행이 어느 회차인가핵심은 마지막 줄의 회차 색인 이다. 성적서 표 한 행이 어느 폴더에서 나왔는지 적어 두면, 클레임이 들어왔을 때 숫자에서 원본까지 한 번에 내려갈 수 있다. 파일 이름 자체의 규칙은 모듈 28 레슨 8에서 정한 형태를 그대로 쓰면 되고, 이 묶음을 얼마나 오래 보유해야 하는지는 모듈 32 레슨 4의 기록 보유 요건이 정한다.
환경이 성적서의 유효 범위를 정한다
환경을 적는 일의 마지막 효과는 주장의 울타리를 치는 것 이다. 환경을 정확히 적으면 그 성적서는 그 환경에 대해 강해지는 대신 그 밖에 대해서는 아무 말도 하지 않는다. 이것은 약점이 아니라 방어선 이다.
그래서 환경 절 끝에는 한계 문구를 한 줄 붙인다.
본 결과는 위에 명시된 환경·구성·데이터 조건에서 측정된 값이며, 다른 하드웨어·소프트웨어 구성이나 다른 데이터 규모에서의 성능을 보장하지 않는다.
이 문구가 없으면 성적서의 숫자가 제품의 고정된 속성 으로 읽힌다. 그러면 고객 환경에서 느릴 때 "성적서가 틀렸다"는 말이 나오고, 있으면 "환경이 다르다"는 대조로 대화가 시작된다.
사례 — "최신 브라우저" 한 줄이 재시험 2주를 만들었다
공공기관 웹 포털의 성능·호환성 시험이었다. 성적서 환경 절의 클라이언트 칸에 "최신 브라우저(Chrome, Edge)" 라고만 적혀 발행됐다. 본문 숫자는 깔끔했다 — 주요 10화면 평균 로딩 1.8초, 95백분위 3.1초, 적합.
7개월 뒤 발주처가 같은 조건으로 확인 시험을 요구했다. 그 사이 Chrome은 메이저 버전이 4개 올라가 있었고, 재측정 결과 95백분위가 4.6초 로 나왔다. 성적서에는 "최신" 이라고만 적혀 있어 어느 버전에서 1.8초였는지 증명할 수 없었다. 다음이 벌어진 일이다.
| 단계 | 소요 | 내용 |
|---|---|---|
| 원본 추적 | 4일 | 측정 PC가 재설치되어 당시 버전 기록이 남아 있지 않았다 |
| 측정 도구 확인 | 3일 | 측정 도구 메이저 버전이 올라가 지표 정의가 바뀌어 있었다 |
| 재시험 | 5일 | 버전을 고정한 두 환경에서 다시 측정 |
| 성적서 개정 | 2일 | 환경 절을 숫자로 다시 쓰고 개정본 발행 |
재시험으로 드러난 원인은 제품이 아니었다. 측정 도구의 지표 정의 변경이 0.9초, 브라우저 버전 차이가 0.5초, 나머지가 7개월간 늘어난 데이터 증가분이었다. 제품 코드는 그대로였다.
바꾼 것은 세 가지였다.
- 환경 절의 모든 버전 칸을 빌드 번호까지 적도록 양식에서 강제
- 측정 PC의 환경 스냅샷을 회차 폴더에 자동 수집 하도록 변경
- 측정 도구 버전을 결과 파일 안에 함께 기록
남는 교훈이 셋이다.
- "최신" 은 값이 아니라 날짜에 의존하는 함수다. 성적서가 읽히는 시점에는 이미 다른 대상을 가리킨다
- 재현 불가능한 성적서의 비용은 재시험 일정으로 청구된다 — 이 건은 사람 2주였고, 처음에 버전을 숫자로 적는 비용은 10분이었다
실무에서 왜 필요한가
환경 기재가 실무에서 힘을 발휘하는 순간은 대개 시험이 끝나고 한참 뒤다.
납품 후 성능 클레임이 들어올 때. "성적서에는 1.2초라는데 실제로는 4초가 나온다"는 연락을 받는다. 이때 환경 절이 잘 쓰여 있으면 대화가 기술적으로 진행된다. "성적서는 데이터 5,000만 건, 단일 인스턴스, 목 PG 기준입니다. 현재 운영은 어느 조건입니까?" 대부분의 클레임이 이 한 번의 대조로 원인이 드러난다. 환경 절이 부실하면 이 대화 자체가 불가능하다.
재시험을 해야 할 때. 결함을 고치고 다시 측정하는데 이전 환경을 그대로 못 갖추면 두 결과를 비교할 수 없다. 개선 폭이 코드 덕인지 환경 덕인지 가릴 수 없기 때문이다. 성능 개선을 주장하려면 환경이 고정되었다는 증거 가 먼저다.
사내 QA에게도 같다. 모듈 14에서 다루는 CI 파이프라인의 성능 회귀 테스트가 자꾸 흔들리는(flaky) 이유 대부분은 환경이 고정되지 않아서다. 러너 인스턴스 타입이 매번 다르거나, 공유 러너에서 다른 잡과 자원을 나눠 쓰는 상황이면 임계값을 어떻게 잡아도 신뢰가 안 생긴다. 성적서 세계의 환경 기재 습관은 그대로 CI 성능 게이트 설계로 옮겨온다.
채용시장에서의 위치
성능·부하 시험 경력을 말할 때 "JMeter를 다룰 줄 안다"와 "재현 가능한 시험 환경을 설계해봤다"는 무게가 다르다. 도구는 며칠이면 배우지만, 환경을 통제하고 그 통제를 문서로 증명하는 일은 경험에서만 나온다.
시험기관 시험원 자리에서는 이 능력이 직무 그 자체다. 성적서 심사에서 지적이 가장 많이 나오는 항목이 환경·조건 기재의 불충분이기 때문이다.
제품사 QA 자리에서도 값이 붙는다. 특히 인증 대응 경험 을 요구하는 공고에서는 "GS인증 시험 때 시험기관이 요구한 환경 구성을 우리 쪽에서 준비해 제출했다"는 이력이 그대로 경쟁력이 된다. 시험기관이 요구하는 환경 문서를 만들어본 사람은 그 반대편 일도 이해하고 있다는 뜻이다.
면접에서는 환경을 "적었는가"가 아니라 "무엇을 기준으로 골랐는가" 를 묻는 쪽으로 질문이 들어온다.
| 질문 | 약한 답 | 강한 답 |
|---|---|---|
| "성적서 환경 절에 무엇을 적으세요?" | "서버 사양과 OS를 적습니다" | "제3자가 재구성할 수 있는 최소 집합입니다. 데이터 규모와 부하 모델이 먼저입니다" |
| "어디까지 적을지 어떻게 정하세요?" | "최대한 많이 적습니다" | "이 값이 달랐다면 결과가 달라졌을까로 가릅니다. 본문 20줄, 나머지는 부록으로 보유합니다" |
| "버전은 어떻게 표기하세요?" | "최신 버전이라고 적습니다" | "버전·빌드 일시·커밋 해시를 함께 적고, 컨테이너는 다이제스트까지 남깁니다" |
| "오토스케일 환경은 어떻게 하세요?" | "클라우드라고 적습니다" | "스케일 고정과 활성 중 목적에 맞게 택하고, 어느 쪽인지 성적서에 명시합니다" |
| "성적서 숫자가 운영과 다르다는 클레임?" | "다시 측정해 봅니다" | "먼저 환경을 대조합니다. 데이터 규모·목 구간·인스턴스 수 세 개에서 대부분 갈립니다" |
두 번째가 가장 변별력이 크다. "최대한 많이 적는다"는 답은 기재의 목적을 재현이 아니라 성실함의 과시로 이해하고 있다는 뜻으로 읽힌다. 환경 절을 여러 번 써 본 사람은 본문이 길어지면 아무도 읽지 않는다 는 것을 경험으로 알고, 그래서 자기 나름의 컷오프 기준을 갖고 있다. 면접관이 보려는 것은 기준의 정답이 아니라 기준이 있다는 사실 이다.
다섯 번째도 깊이가 드러난다. 클레임에 곧바로 재측정으로 반응하는 사람은 며칠을 쓰고도 원인을 못 찾는다. 환경 대조를 먼저 하는 사람은 반나절 안에 차이의 출처를 좁힌다.