개념
흔히 보는 네트워크 조건 엑셀
많은 팀에 이런 파일이 하나씩 있다. 시트 하나에 조건이 행으로 쭉 나열된 표다. 실제 사례 하나를 뜯어보자.
[전형적인 네트워크 조건 시트의 구조]
1행 UP 네트워크 (A~C) | Down 네트워크 (D~F)
2행 Packet Loss(%) | Latency(ms) | Bandwidth(mbps) ×2
3~10행 조건 8개
(0, 40, 100) (0, 40, 50) (0, 40, 30) (0, 40, 10) ← 대역폭 훑기
(0, 80, 100) (0,120,100) (0,150,100) (0,200,100) ← 지연 훑기
11~18행 위 8개와 완전히 동일한 값 반복
19행 두 번째 헤더 — Packet Loss Rate | Latency | Bandwidth
20~33행 조건 7개, 각각 2행씩 중복
(0, 300, 1) (0.15, 200, 1) (0.1, 50, 3) (0.05, 50, 3)
(0.01, 50, 3) (0.005, 50, 3) (0.005, 5, 5)이 표는 쓸모없지 않다. 조건을 수치로 적어둔 것만으로도 아무것도 없는 것보다 낫다. 다만 이걸 그대로 테스트 케이스라고 부르면 곤란하다. 문제를 하나씩 짚어보자.
문제 ① — 이건 조건 매트릭스지 테스트 케이스가 아니다
테스트 케이스에 반드시 있어야 할 칸이 통째로 없다.
| 있어야 할 칸 | 이 시트에 있는가 |
|---|---|
| 케이스 ID | ❌ |
| 대상 기능·시나리오 | ❌ |
| 실행 절차 | ❌ |
| 기대 결과 | ❌ |
| 판정 기준 | ❌ |
| 실행 결과·증거 | ❌ |
| 조건 (4축 수치) | ⭕ |
조건만 있고 "그래서 무엇을 확인하는가"가 없다. 레슨 7의 결론을 다시 떠올리자 — 네트워크 테스트는 느려지는지가 아니라 느려졌을 때 제품이 어떻게 행동하는지를 본다. 이 시트로는 그 판정을 할 수 없다.
문제 ② — 상·하향이 항상 같다
UP 열과 Down 열의 값이 모든 행에서 동일 하다. 레슨 1에서 강조한 비대칭이 한 번도 테스트되지 않는다는 뜻이다.
업로드 경로를 가진 기능(사진 첨부, 파일 전송, 긴 폼 제출)의 결함은 이 표로는 절대 안 나온다.
문제 ③ — 행이 중복되어 있다
310행과 1118행이 완전히 같고, 20~33행도 두 행씩 짝지어 같다.
아마 iOS/Android 구분이나 2회 반복 실행 의도 였을 텐데, 그것을
나타내는 칸이 없어서 지금은 그냥 중복으로 보인다.
의도가 있었다면 칸을 만들어야 한다. 없었다면 절반은 지워야 한다. 어느 쪽이든 지금 상태는 읽는 사람을 헷갈리게 한다.
문제 ④ — 한 시트에 단위가 다른 두 표가 섞여 있다
19행에 두 번째 헤더가 끼어 있고, 헤더 이름도 다르다.
2행 Packet Loss (%) → 퍼센트 단위로 읽힌다
19행 Packet Loss Rate → 비율 단위
실제 값: 0.15 / 0.1 / 0.05 / 0.01 / 0.005
→ 비율로 읽으면 15% / 10% / 5% / 1% / 0.5%
→ 퍼센트로 읽으면 0.15% / 0.1% / ... (100배 차이)한 시트 안에서 같은 이름의 열이 다른 단위를 쓴다. 레슨 2에서 다룬 단위 혼동이 문서 자체에 내장되어 있는 셈이다. 도구에 입력하는 사람이 100배를 틀릴 수 있다.
참고로
0.005가 셀에5.0000000000000001E-3으로 저장되어 있다. 스프레드시트의 부동소수점 표현 때문인데, 이런 값을 스크립트로 읽어 자동화에 넘길 때 문자열 비교가 깨지는 원인이 된다.
문제 ⑤ — 빠진 축과 빠진 상태
축: 대역폭 ⭕ 지연 ⭕ 손실 ⭕ 지터 ❌
상태: 정상 ⭕ 저하 ⭕ Limited ❌ 단절 ❌
기타: DNS ❌ 비대칭 ❌ 부하 중 응답성 ❌레슨 1에서 다룬 4축 중 지터가 없고, 4단계 상태 중 가장 사고가 많이 나는 Limited Service가 없다.
문제 ⑥ — 설계 기법이 없다
3~10행을 보면 한 번에 하나씩만 바꾸는(one-factor-at-a-time) 방식이다. 대역폭을 훑고, 지연을 훑고. 이건 특성 파악에는 좋지만 실제 사용자가 겪는 조합 — 대역폭도 낮고 지연도 높고 손실도 있는 상태 — 을 거의 만들지 않는다.
모듈 3에서 배운 조합 설계 기법이 하나도 적용되지 않았다.
재설계 — 두 개의 문서로 나눈다
해결은 간단하다. 조건과 케이스를 분리한다.
문서 A — 조건 정의서 (조건 하나당 한 행)
조건 식별자 | 4축 수치 | 상·하향 구분 | 도구별 설정값 | 스크립트명
문서 B — 테스트 케이스 (케이스 하나당 한 행)
케이스 ID | 대상 기능 | 조건 식별자(참조) | 절차 | 기대 결과 | 판정 기준조건은 재사용되고 케이스는 기능마다 다르다. 둘을 한 표에 섞으면 조건이 바뀔 때마다 모든 케이스를 고쳐야 한다.
문서 A — 조건 정의서
| 식별자 | 손실 | 지연 | 지터 | 다운 | 업로드 | 목적 |
|---|---|---|---|---|---|---|
NET-0 정상 | 0 % | 40 ms | 0 | 100 Mbps | 100 Mbps | 기준선 |
NET-1 보통 | 0.5 % | 50 ms | 10 ms | 30 Mbps | 10 Mbps | 일반 사용 |
NET-2 열악 | 5 % | 150 ms | 30 ms | 10 Mbps | 2 Mbps | 로딩·타임아웃 |
NET-3 극단 | 15 % | 300 ms | 100 ms | 1 Mbps | 0.3 Mbps | 재시도·중복 |
NET-4 Limited | 30 % | 1,000 ms | 200 ms | 0.1 Mbps | 0.05 Mbps | 사용 불가 대응 |
NET-5 단절 | 100 % | — | — | 0 | 0 | 오프라인 경로 |
NET-6 업로드 편중 | 2 % | 150 ms | 30 ms | 20 Mbps | 0.3 Mbps | 업로드 경로 |
NET-7 DNS 지연 | 0 % | 40 ms | 0 | 100 Mbps | 100 Mbps | DNS 실패 (+DNS 지연) |
NET-6 이 문제 ②를 해결하고, NET-4·NET-5·NET-7 이 문제 ⑤를
해결한다. 지터 칸이 추가되어 문제 ⑤의 나머지도 해결된다.
도구별 설정값 환산표
조건 정의서의 각 행을 도구 입력값으로 환산한 표를 함께 둔다. 레슨 2에서 강조한 단위 혼동을 문서 차원에서 막는 장치다.
| 조건 | 손실 | 지연 | 대역폭 | iOS NLC | Android (B/s) | tc netem | Clumsy (KB/s) |
|---|---|---|---|---|---|---|---|
| 이상적 | 0 % | 40 ms | 100 Mbps | 사용자 정의 | 제한 없음 | rate 100mbit delay 40ms | 12,500 |
| 보통 | 0.5 % | 50 ms | 30 Mbps | 사용자 정의 | 3,750,000 | rate 30mbit delay 50ms loss 0.5% | 3,750 |
| 열악 | 5 % | 150 ms | 10 Mbps | 3G 근사 | 1,250,000 | rate 10mbit delay 150ms loss 5% | 1,250 |
| 극단 | 15 % | 300 ms | 1 Mbps | Very Bad Network | 125,000 | rate 1mbit delay 300ms loss 15% | 125 |
| Limited | 30 % | 1,000 ms | 0.1 Mbps | 사용자 정의 | 12,500 | rate 100kbit delay 1000ms loss 30% | 12 |
| 단절 | 100 % | — | 0 | 100% Loss | — | loss 100% | Drop 100% |
단위 규칙을 표 아래에 못 박는다. 손실은 퍼센트(%) 로 적는다. 비율(0.05) 표기를 쓰지 않는다.
Mbps → KB/s는×1000÷8,Mbps → B/s는×1,000,000÷8.
문서 B — 테스트 케이스
| 케이스 ID | 대상 기능 | 조건 | 절차 | 기대 결과 | 판정 기준 |
|---|---|---|---|---|---|
TC-NET-001 | 상품 목록 로딩 | NET-2 | 앱 콜드 스타트 → 목록 진입 | 3초 내 스켈레톤, 10초 내 첫 화면 | 무한 스피너 없음 |
TC-NET-002 | 주문 생성 | NET-3 | 주문 버튼 5회 연타 | 요청 1건, 주문 1건 | 중복 0건 |
TC-NET-003 | 사진 첨부 | NET-6 | 5MB 이미지 업로드 | 진행률 표시, 취소 가능 | 진행률이 멈추지 않음 |
TC-NET-004 | 글 작성 | NET-5 | 긴 글 입력 → 등록 | 실패 안내 + 입력값 보존 | 내용 유실 없음 |
TC-NET-005 | 앱 전체 | NET-7 | 콜드 스타트 후 주요 화면 순회 | 네트워크 오류 안내 | 크래시 0건 |
모든 행에 기대 결과와 판정 기준이 있다. 이제 통과·실패를 말할 수 있다. 이게 조건 매트릭스와 테스트 케이스의 차이다.
조합 설계 — 몇 개를 만들 것인가
조건 8개 × 기능 20개 = 160건. 매 릴리즈에 다 돌릴 수는 없다. 모듈 3·4에서 배운 것을 쓴다.
[층을 나눈다]
스모크 (매 빌드) NET-2 × 핵심 기능 5개 = 5건
회귀 (매 릴리즈) NET-1~4 × 핵심 기능 10개 = 40건
전체 (분기·대규모 변경) NET-0~7 × 기능 20개 = 160건
[조합 선택 근거]
- 레슨 1 과제 2의 '화면별 민감 축' 표를 쓴다
→ 대역폭 민감 화면은 NET-2·3 필수
→ 지연 민감 화면은 NET-3·4 필수
→ 업로드 있는 기능은 NET-6 필수
- 레슨 7의 '돈과 직결되는' 기능(결제·주문)은 전 조건 필수모든 조합을 다 돌리는 것이 목표가 아니다. 리스크가 높은 곳에 조건을 몰아주는 것이 목표다.
자동화 — 조건을 코드로 바꾼다
어디까지 자동화되는가
자동화 잘 됨 조건 적용, 화면 전이, 요청 수 세기, 응답 시간 측정
자동화 어려움 "레이아웃이 깨졌는가", "안내 문구가 적절한가"
→ 시각 회귀(모듈 16 레슨 8)와 사람 판단을 병행조건 적용과 수치 판정은 자동화하고, 화면 품질 판단은 사람이 본다. 이 경계를 처음에 정해두지 않으면 자동화가 과욕으로 끝난다.
Android 에뮬레이터
실기기 확보 전 사전 확인이나 다기기 회귀 자동화에 쓴다.
# 실행 시 지정
emulator -avd <이름> -netspeed edge -netdelay umts
# 실행 중 변경
adb emu network speed edge
adb emu network delay 500
adb emu network speed full # 원복확장 컨트롤(Extended controls)의 Cellular 탭에서 네트워크 종류와 신호 세기(None / Poor / Moderate / Good)를 바꾸면 신호 약함 상태 도 재현된다.
한계가 분명하다. 실기기 라디오 동작(핸드오버, 절전 진입, 실제 전력 소모)은 재현되지 않는다. 레슨 7의 ⑦ 회선 전환과 ⑧ 자원 소모는 에뮬레이터로 검증할 수 없다.
웹 자동화 — Playwright + CDP
Playwright에는 네트워크 스로틀링 API가 내장되어 있지 않지만, Chrome DevTools Protocol 을 통해 DevTools 네트워크 패널과 같은 기능을 쓸 수 있다.
const client = await context.newCDPSession(page);
await client.send('Network.emulateNetworkConditions', {
offline: false,
downloadThroughput: 10 * 1000 * 1000 / 8, // 10 Mbps → B/s
uploadThroughput: 2 * 1000 * 1000 / 8, // 2 Mbps → B/s
latency: 150, // ms
connectionType: 'cellular3g',
});주의할 점 셋.
- 단위가 바이트/초 다. Android 개발자 옵션과 같다. 레슨 2의 환산을 쓴다
downloadThroughput과uploadThroughput을 따로 줄 수 있다 →NET-6같은 비대칭 조건을 여기서 만들 수 있다- 손실률은 지정할 수 없다. 4축 중 셋만 제어된다. 손실이 필요하면 레슨 5의 tc netem으로 간다
offline: true 로 단절(NET-5)도 만들 수 있다.
모바일 자동화 — 클라우드 디바이스 팜
BrowserStack, Sauce Labs 등은 원격 실기기에 네트워크 프로파일을 적용하는 기능을 제공한다.
| 항목 | 내용 |
|---|---|
| 장점 | 보유하지 않은 기종·OS 버전까지 동일 조건으로 검증 |
| 기능 | 다운로드·업로드 속도, 지연, 손실, 오프라인 상태 지정 |
| 연동 | Appium 등 자동화 스크립트에서 조건 전환 가능 |
| 비용 | 유료 구독 |
| 확인 사항 | 사외 반출 정책 — 실기기가 외부에 있다 |
마지막 항목은 기술이 아니라 규정 문제다. 사내 빌드와 테스트 계정이 외부 서비스로 나간다는 뜻이므로 도입 전 보안·법무 확인 이 필요하다.
리눅스 랩을 CI에 붙이기
레슨 5에서 만든 스크립트를 파이프라인에서 호출하는 것이 가장 재현성이 높은 자동화다.
[파이프라인 골격]
1. reset.sh 이전 조건 제거
2. tc qdisc show 현재 상태 기록 (로그에 남긴다)
3. poor.sh 조건 적용
4. 적용 확인 (iperf3 또는 ping) → 목표 ±20% 검증, 벗어나면 중단
5. 테스트 실행
6. reset.sh 원복
7. 결과 + 적용 확인 로그를 아티팩트로 보관4단계가 핵심이다. 조건이 안 걸린 채로 테스트가 통과하는 것을 파이프라인이 스스로 막는다. 레슨 2의 "설정했다 ≠ 적용되었다"를 기계가 검증하게 만드는 것이다.
실제 열악 환경 — 자동화를 보완한다
도구로 만든 조건은 재현성이 높지만 실제와는 다르다. 보완 수단이 있다.
- 데이터 소진 후 속도 제한이 걸린 회선 활용
- 선호 네트워크를 3G로 하향
- 지하주차장·엘리베이터 등 음영 지역 이동
- 기내모드와 Wi-Fi 전환 반복실제 사용자 상황에 가장 가깝지만 재현성이 낮아 회귀에는 부적합하다. 탐색적 테스팅(모듈 5) 세션으로 잡아 돌리고, 여기서 발견한 문제를 도구 기반 조건으로 재현해 회귀에 넣는 순서가 맞다.
상황별 권장 조합
| 상황 | 권장 방법 | 이유 |
|---|---|---|
| iOS 앱만 테스트 | 레슨 3 ① NLC | 장비 없이 즉시 적용. DNS 지연까지 재현 |
| Android 앱만 | 레슨 3 ② → 없으면 레슨 4 프록시 | 기기 지원 시 가장 간단 |
| 두 OS 동시·회귀 반복 | 레슨 5 리눅스 AP | OS 무관, 조건이 명령으로 남아 재현성 최고 |
| 특정 API만 느리게·오류 주입 | 레슨 4 프록시 | 호스트별 제어와 응답 조작 |
| Windows 구성 유지 | clumsy-hotspot 또는 상용 에뮬레이터 | 포워드 계층 지원 도구로 교체 |
| 보유하지 않은 기종 | 클라우드 디바이스 팜 | 기기 확보 없이 다양한 조합 |
| 웹 자동화 | Playwright + CDP | 손실은 못 걸지만 CI에 붙이기 쉽다 |
우선 적용 순서: iOS는 NLC, Android는 개발자 옵션이나 프록시로 이번 주 안에 재현을 확보 하고, 회귀가 반복되기 시작하면 리눅스 AP를 팀 공용 랩으로 구축한다.
실무에서 왜 필요한가
엑셀이 실행 가능해진다
조건만 적힌 표는 "이걸로 뭘 하라는 거지"라는 질문을 남긴다. 케이스로 분리하고 기대 결과를 넣으면 새로 온 사람이 그대로 실행할 수 있다. 인수인계 비용이 크게 줄어든다.
릴리즈 판정이 가능해진다
"NET-1~4 × 핵심 기능 10개 = 40건 중 38건 통과, 미통과 2건은 결함 #481·#482"라고 말할 수 있게 된다. 모듈 4의 종료 조건을 네트워크 축에도 적용한 것이다.
회귀 비용이 예측 가능해진다
조건과 케이스가 분리되어 있으면 "조건 하나를 추가하면 케이스가 몇 개 늘어나는가"를 곱셈으로 계산할 수 있다. 자동화 투자 판단의 근거가 된다.