개념
같은 현상, 두 개의 리포트
QA가 같은 버그를 발견했다. 리포트가 두 가지로 나온다.
A: "주문하기 버튼을 눌렀는데 아무 반응이 없어요."
B: "주문하기 클릭 시
POST /api/orders가 500 을 반환합니다. 응답 본문은{"error":"COUPON_EXPIRED"}이고, 화면에는 아무 메시지도 표시되지 않습니다. 콘솔에Uncaught TypeError: Cannot read properties of null (reading 'message')가 함께 찍힙니다. HAR 첨부했습니다."
두 리포트의 차이는 관찰력이 아니라 도구 다. B를 쓴 사람은 특별히 더 꼼꼼한 게 아니라, 브라우저 개발자도구를 열어봤을 뿐이다.
레슨 2에서 HTTP를, 레슨 1에서 코드 읽기를 배웠다. 이 레슨은 그 지식을 실제 화면에서 확인하는 도구 를 다룬다. 그리고 다음 레슨(레슨 10)에서 "개발자도구로 안 되는 것들"을 위해 Charles·Wireshark로 넘어간다 — 그 전에 되는 것부터 제대로 하자는 것이 이 레슨이다.
여는 방법:
F12또는Ctrl+Shift+I(맥은Cmd+Option+I). 특정 요소를 바로 보려면 그 요소에서 우클릭 → 검사.
QA가 실제로 쓰는 패널
패널이 많지만 QA가 쓰는 것은 정해져 있다.
| 패널 | 무엇을 보나 | QA가 쓰는 상황 |
|---|---|---|
| Network | 서버와 오간 모든 요청 | 가장 많이 쓴다. 결함 원인의 절반이 여기서 보인다 |
| Console | 에러·경고 메시지 | 화면에는 안 보이는 실패가 여기 찍힌다 |
| Elements | 현재 DOM과 스타일 | 로케이터 확인, 레이아웃·접근성 점검 |
| Application | 쿠키·로컬스토리지·세션 | 로그인 상태, 저장된 값 확인 |
| Sources | 실제 실행되는 코드 | 값이 어디서 바뀌는지 추적(선택) |
| Lighthouse | 성능·접근성·SEO 자동 진단 | 비기능 초벌 점검 |
| Performance | 렌더링·스크립트 실행 타임라인 | "느리다"의 원인 좁히기 |
Network와 Console 둘만 익혀도 결함 리포트의 질이 달라진다. 나머지는 필요할 때 하나씩 늘리면 된다.
UI는 크롬 버전마다 조금씩 바뀐다. 최근 버전에는 AI 지원 패널이나 자동화 연동(DevTools MCP 서버 — 모듈 18a 레슨 4의 그 MCP다) 같은 것도 들어와 있다. 패널 위치를 외우기보다 "무엇을 보고 싶은가"로 찾는 습관 이 오래 간다.
Network 탭 — 여기가 본진이다
버그를 만나면 가장 먼저 열 곳이다. 먼저 켜두어야 할 설정 두 개 가 있다.
| 설정 | 왜 |
|---|---|
| Preserve log(로그 보존) | 페이지가 이동·새로고침돼도 기록이 남는다. 이걸 안 켜면 결정적인 요청이 사라진다 |
| Disable cache(캐시 사용 중지) | 캐시 때문에 요청이 안 나가는 것을 막는다. DevTools가 열려 있을 때만 적용된다 |
로그인 → 리다이렉트 흐름을 볼 때 Preserve log를 안 켜두면 로그인 요청이 화면 전환과 함께 사라진다. 처음 열 때 두 개를 켜는 것을 습관으로 만들어두면 같은 재현을 두 번 하지 않아도 된다.
요청 목록에서 읽을 것들
| 열 | 무엇을 말하나 |
|---|---|
| Name | 요청 경로 |
| Status | 200/201, 4xx(요청 문제), 5xx(서버 문제) — 레슨 2에서 배운 그것 |
| Type | xhr/fetch(API), document, script, img … |
| Size | 응답 크기. (disk cache) 면 서버에 안 갔다는 뜻 |
| Time | 소요 시간. 느린 요청을 찾을 때 |
| Waterfall | 시간 축에서 언제 시작·끝났는지 |
필터를 쓰면 훨씬 빨라진다.
Fetch/XHR 버튼 API 호출만 남긴다 — QA가 가장 자주 쓴다
status-code:500 상태 코드로 필터
method:POST 메서드로 필터
-domain:*.google.com 특정 도메인 제외 (앞의 - 는 제외)
larger-than:1M 1MB 넘는 응답만 — 성능 문제 찾을 때요청 하나를 클릭하면 상세가 열린다. QA가 볼 탭은 넷이다.
- Headers — 요청 URL, 메서드, 상태 코드, 요청·응답 헤더. 인증 토큰이 실려 나갔는지 여기서 확인한다(레슨 3)
- Payload — 우리가 보낸 값. "내가 입력한 값이 실제로 이렇게 전달됐나" 를 확인하는 자리
- Response / Preview — 서버가 준 값. Preview는 JSON을 접었다 펼 수 있어 읽기 편하다
- Timing — 어디서 시간을 썼는지(대기·다운로드 등)
결함 원인을 가르는 질문은 대개 이 순서로 풀린다.
① 요청이 아예 안 나갔다 → 프런트엔드 문제 (이벤트·검증에서 막힘)
② 요청은 나갔는데 4xx → 요청 값이 잘못됨 (Payload를 본다)
③ 요청은 맞는데 5xx → 서버 문제 (개발자에게 넘길 근거 확보)
④ 200인데 화면이 이상 → 프런트엔드 렌더링 문제 (Console을 본다)이 네 갈래를 구분하는 것만으로 리포트의 가치가 완전히 달라진다. "안 돼요"가 아니라 "요청 자체가 안 나갑니다" 또는 "서버가 500을 줍니다"가 되고, 그러면 담당자가 바로 정해진다.
네트워크 조건 바꿔보기
Network 탭에서 쓰로틀링(Throttling) 으로 느린 네트워크를 흉내낼 수
있다. Fast 4G, Slow 4G, Offline 같은 프리셋이 있고 직접 만들 수도
있다.
QA에게 이게 중요한 이유는, 개발자는 대부분 빠른 회선에서 개발하기 때문 이다. 느린 환경에서만 드러나는 결함이 있다.
| 쓰로틀링으로 잡는 결함 |
|---|
| 로딩 중 상태가 없어 화면이 빈 채로 멈춤 |
| 응답 전에 버튼을 두 번 눌러 중복 요청(중복 주문!) |
| 타임아웃 처리가 없어 영원히 스피너만 돎 |
| 순서가 보장되지 않아 나중 응답이 먼저 온 결과를 덮어씀 |
| 이미지가 늦게 와서 레이아웃이 밀림 |
Offline 모드 도 유용하다. 오프라인일 때 적절한 안내가 뜨는지, 복구되면 자동으로 재시도하는지 확인한다.
HAR — 네트워크 기록을 통째로 넘기기
HAR(HTTP Archive) 은 Network 탭의 기록 전체를 파일로 저장한 것이다. 요청 목록에서 우클릭 → Save all as HAR 로 내보낸다.
개발자에게 이 파일을 주면 재현 없이도 무엇이 오갔는지 그대로 볼 수 있다. 재현이 어려운 결함일수록 값이 크다. 모듈 5(레슨 12)에서 다룬 "재현 불가능한 버그"에 대한 대응 수단이기도 하다.
⚠️ HAR에는 인증 토큰·쿠키·개인정보가 그대로 들어 있다. 외부에 공유할 때는 민감 정보 제거 옵션(
Sanitized형태)을 쓰거나, 필요한 요청만 골라 내보낸다. 모듈 18b(레슨 9)에서 다룬 원칙이 여기에도 적용된다 — 로그를 붙여 넣기 전에 무엇이 들어 있는지 본다. 특히 HAR을 AI에 그대로 붙여 넣는 것은 위험하다.
Console — 화면에 안 보이는 실패가 찍히는 곳
화면은 멀쩡한데 기능이 안 되는 경우, 원인이 여기 있는 경우가 많다.
Uncaught TypeError: Cannot read properties of null (reading 'message')
at showError (order.js:142:18)
at handleSubmit (order.js:88:5)레슨 1에서 배운 스택 트레이스 읽기가 여기서 쓰인다. 아래에서 위로
읽으면 호출 순서이고, order.js:142 가 실제로 터진 지점이다.
QA가 콘솔에서 챙길 것들이다.
| 유형 | 의미 |
|---|---|
| 빨간 에러 | 코드가 실제로 터졌다. 대부분 보고 대상 |
| 노란 경고 | 당장은 아니지만 문제가 될 수 있음(폐기 예정 API 등) |
| CORS 에러 | 서버 설정 문제. 프런트가 아니라 백엔드 이슈인 경우가 많다 |
| Mixed content | HTTPS 페이지에서 HTTP 자원 로드 — 보안 경고 |
| 404 리소스 | 이미지·스크립트가 없음. 화면 깨짐의 원인 |
Console에 에러가 있는데 화면에는 아무 표시가 없다 — 이건 그 자체로 결함이다. 사용자는 무슨 일이 일어났는지 알 수 없기 때문이다.
콘솔에서 값을 직접 확인할 수도 있다. 자동화 로케이터를 검증할 때 특히 유용하다.
// 이 선택자로 요소가 몇 개 잡히나 (자동화 로케이터 검증)
document.querySelectorAll('[data-testid="order-btn"]').length
// 마지막으로 검사한 요소
$0
// jQuery 스타일 단축 선택자 (DevTools 내장)
$$('.product-card').length두 번째 줄이 실무에서 값을 한다. 모듈 13(레슨 3)에서 배운 안정적인 로케이터를 만들 때, 정말 유일하게 잡히는지 를 여기서 즉시 확인할 수 있다. 1이 아니면 그 로케이터는 불안정하다.
Elements — DOM과 화면의 실제 상태
Elements 패널은 지금 화면에 그려진 실제 DOM 을 보여준다. 원본 HTML이 아니라 자바스크립트가 조작한 이후의 상태다.
QA가 쓰는 방법 셋이다.
1) 로케이터 후보 찾기. 요소를 우클릭 → Copy → Copy selector /
Copy XPath. 다만 복사한 선택자를 그대로 자동화에 쓰면 안 된다 —
div > div:nth-child(3) > span 같은 형태라 구조가 조금만 바뀌어도
깨진다. data-testid 같은 안정적인 속성이 있는지 먼저 본다.
2) 값을 바꿔 즉석 테스트. DOM을 직접 편집해 긴 텍스트·특수문자를 넣어보면 레이아웃이 깨지는지 바로 보인다. 실제 데이터를 만들지 않고도 경계값을 확인할 수 있다.
3) 접근성 확인. 요소를 선택하면 접근성 트리와 이름(name)·역할(role)이 보이고, 색상 대비도 표시된다. 모듈 16(레슨 7)의 WCAG 점검을 여기서 초벌로 할 수 있다.
기기 에뮬레이션(Toggle device toolbar, Ctrl+Shift+M)도 알아두자.
화면 크기·터치·기기 픽셀 비율을 흉내낸다. 다만 한계가 분명하다 —
실제 기기의 브라우저 엔진·성능·제스처와는 다르다. 모듈 17에서
다루는 모바일 테스트를 대체하지 못하고, 1차 확인용 이다.
Application — 로그인 상태와 저장된 값
레슨 3에서 배운 세션·토큰이 실제로 어디에 저장되는지 보는 곳이다.
| 항목 | 확인할 것 |
|---|---|
| Cookies | 세션 쿠키, 만료 시각, HttpOnly·Secure·SameSite 속성 |
| Local Storage | 토큰이 여기 있다면 XSS에 노출될 수 있다(보안 관점) |
| Session Storage | 탭을 닫으면 사라지는 값 |
| Clear site data | 로그아웃·초기 상태 테스트에 유용 |
마지막 줄이 실무에서 자주 쓰인다. "신규 사용자 상태"를 재현하려고 매번 계정을 새로 만들 필요 없이, 사이트 데이터를 지우면 상당수의 초기 상태가 재현된다.
쿠키의 HttpOnly 속성 확인도 QA의 점검 항목이다 — 인증 쿠키에 이 속성이
없으면 자바스크립트로 읽을 수 있고, 그건 모듈 16(레슨 5)에서 배운 취약점
경로가 된다.
Lighthouse와 Performance — 비기능 초벌 점검
Lighthouse 는 버튼 한 번으로 성능·접근성·SEO·모범사례를 진단해 점수와 개선 항목을 준다. 모듈 16(레슨 4)에서 배운 Core Web Vitals가 여기서 측정된다.
주의할 점 — Lighthouse 점수는 실행할 때마다 흔들린다. 네트워크· CPU 상태에 영향을 받기 때문이다. 점수 하나로 판정하지 말고 추세와 개선 항목 목록을 본다. 모듈 14(레슨 7)에서 SLI를 다룰 때 한 이야기와 같다 — 합성 측정과 실사용자 측정은 다르다.
Performance 패널은 더 깊다. 녹화 후 어느 스크립트가 얼마나 오래 실행됐는지, 긴 작업(long task)이 어디 있는지 보여준다. QA가 여기까지 갈 필요는 대개 없지만, "이 화면이 느리다"를 개발자에게 넘길 때 녹화 파일을 함께 주면 대화가 빨라진다.
증거를 남기는 법 — 리포트에 무엇을 첨부하나
DevTools를 여는 목적은 결국 재현 가능한 리포트 다. 모듈 6(레슨 2)에서 배운 좋은 결함 리포트에 이 레슨의 도구가 더하는 것들이다.
| 증거 | 언제 첨부 |
|---|---|
| 실패 요청 스크린샷(Headers + Response) | 거의 항상 |
| 콘솔 에러 전문(스택 트레이스 포함) | 에러가 찍혔다면 |
| HAR 파일 | 재현이 어렵거나 요청 흐름이 복잡할 때 |
| 화면 녹화 | 타이밍·애니메이션 관련, 재현 절차가 긴 경우 |
| Performance 녹화 | 성능 문제 |
| 네트워크 조건 | 쓰로틀링을 걸어 재현했다면 반드시 명시 |
마지막 줄을 빠뜨리면 개발자가 재현하지 못한다. "Slow 4G에서만 재현됩니다"는 결정적인 정보다.
그리고 첨부 전에 확인할 것 하나 — 민감 정보. 스크린샷에 토큰이, HAR에 개인정보가 들어 있을 수 있다. 이슈 트래커는 대개 팀 전체가 보고, 때로는 협력사도 본다.
개발자와 통하는 언어
이 레슨의 도구들이 만드는 실질적 변화는 리포트의 문장 이다.
| 이렇게 말하는 대신 | 이렇게 |
|---|---|
| "저장이 안 돼요" | "PUT /api/profile 가 400, 응답에 INVALID_PHONE_FORMAT" |
| "화면이 깨져요" | "GET /images/banner.png 가 404, 콘솔에 로드 실패 에러" |
| "느려요" | "GET /api/products 응답에 4.2초, 그중 대기 3.8초" |
| "가끔 안 돼요" | "Slow 4G에서 5회 중 3회 재현, 중복 POST 2건 발생. HAR 첨부" |
오른쪽 문장들은 담당자를 특정한다. 400이면 요청을 보내는 쪽, 500이면 서버, 404 리소스면 배포·정적 파일. 모듈 6(레슨 3)에서 배운 비난 없는 소통과도 맞는다 — 사람을 지목하는 대신 사실을 제시 하기 때문이다.
실무에서 왜 필요한가
DevTools는 QA가 가장 자주 쓰게 되는 도구인데, 정작 체계적으로 배우는 경우가 드물다. 대개 "Network 탭에서 빨간 줄 찾기" 정도로 쓰다가 멈춘다. Preserve log 하나만 켜둬도 같은 재현을 두 번 하지 않아도 된다는 것을 아는 사람과 모르는 사람의 하루가 다르다.
그리고 이 도구는 QA의 위치를 바꾼다. "안 됩니다"만 전달하는 사람과 "이 요청이 이 응답을 줍니다"를 전달하는 사람은 개발팀에서 받는 대우가 다르다. 후자는 원인 범위를 좁혀주기 때문에 실제로 팀의 시간을 아낀다.
기초 도구라고 넘기기 쉽지만, 뒤에 오는 것들의 전제이기도 하다. 자동화 로케이터 검증(모듈 13), 성능 초벌 점검(모듈 16), API 요청 확인(모듈 12)이 전부 이 화면에서 시작한다. 다음 레슨(레슨 10)의 Charles·Wireshark는 여기서 안 되는 것 을 위한 도구이므로, 여기가 먼저다.