본문 바로가기

Coding, Testing, Challenge

화면이 멈춘 게 아니라, 세 가지가 각각 달랐습니다

멈춘 것처럼 보인 세 가지

사용자 신고는 늘 한 문장입니다. "화면이 멈춰요." 그런데 원인은 세 개였고, 하나도 겹치지 않았습니다.

멈춘 것처럼 보이는 세 가지 함정
셋 다 오류가 나지 않고, 콘솔도 깨끗합니다

① 브라우저가 굳었습니다

조회 결과 15만 행을 한 번에 그리고 있었습니다.

let html = '';
rows.forEach(r => { html += '<tr>...</tr>'; });
tbody.innerHTML = html;   // ← 여기서 브라우저가 멈춥니다

가장 헷갈렸던 건 로딩 표시조차 안 돈다는 점이었습니다.

화면을 그리는 일과 애니메이션은 같은 한 줄에 서 있습니다. 그리기가 그 줄을 붙들고 있으면 로딩 표시도 같이 멈춥니다. 그래서 사용자 눈에는 "아무 반응이 없음" 으로 보입니다. 느린 게 아니라 죽은 것처럼 보입니다.

고친 방법은 단순합니다. 화면에는 한 페이지만 그립니다. 15만 행을 사람이 볼 일이 없습니다.

② 스타일이 안 먹었습니다

페이지 번호를 붙였는데, 화면에 이렇게 나왔습니다.

· 1
· 2
· 3

가로로 붙은 버튼이 아니라 세로 점 목록이었습니다.

스타일 규칙이 그 조각 안의 <style> 태그에만 들어 있었습니다. 원래 화면은 그 조각을 통째로 불러와서 괜찮았는데, 페이지 번호는 자바스크립트가 나중에 만들어 붙였습니다. 그러니 그 규칙이 안 닿습니다.

공용 스타일 파일로 옮기니 바로 해결됐습니다. 그런데 그러고도 점이 남아서, 목록 점을 지우는 규칙을 따로 넣어야 했습니다. 한 번에 안 끝났습니다.

③ 아무 일도 일어나지 않았습니다

화면을 처음 열면 기본값으로 최근 8개년을 채워 주기로 했습니다. 함수도 있었고, 테스트도 통과했습니다.

그런데 화면에는 안 나왔습니다.

function fillDefaultYears() { ... }   // 잘 만들어져 있음
// 부르는 곳: 없음

이 함수를 부르는 곳이 한 군데도 없었습니다.

테스트는 함수를 직접 불러서 확인하고 있었습니다. 그러니 초록불입니다. "화면이 열릴 때 이 함수가 불린다"는 걸 아무도 검사하지 않았습니다.

왜 셋 다 늦게 찾았나

공통점이 있습니다.

오류가 나지 않습니다. 콘솔도 깨끗합니다.

개발자는 문제가 생기면 콘솔부터 봅니다. 깨끗하면 "내 쪽은 아니네" 하고 서버를 봅니다. 서버도 정상이면 그때부터 헤맵니다.

그리고 신고는 전부 같은 문장으로 들어옵니다. "멈춰요." 세 개가 다른 문제라는 걸 알아채는 데 시간이 걸렸습니다.

지금은 이렇게 구분합니다

이렇게 보이면이쪽입니다
로딩 표시조차 안 돈다브라우저가 굳음 — 그리는 양을 줄이세요
로딩 표시는 도는데 오래 걸린다서버·네트워크
모양만 이상하다스타일이 안 닿음 — 나중에 만든 요소인지 보세요
아무 변화가 없다그 코드가 안 불림 — 호출부를 찾아보세요

로딩 표시가 도는지 하나로 절반이 갈립니다. 사용자에게 물어볼 수 있는 가장 값진 질문입니다.

회귀 테스트로 막았습니다

셋 다 다시 들어올 수 있는 종류입니다. 그래서 각각 테스트를 남겼습니다.

  • 한 번에 그리는 행 수가 정해진 값을 넘지 않는지
  • 나중에 만든 요소에도 스타일 클래스가 붙는지
  • 화면을 열었을 때 기본값이 실제로 채워지는지

세 번째가 핵심입니다. 함수를 직접 부르는 테스트가 아니라 화면을 여는 테스트여야 합니다.

가져갈 것

  • "멈췄다"는 진단이 아닙니다. 최소 세 갈래입니다.
  • 로딩 표시가 도는지부터 확인하세요. 안 돌면 서버가 아니라 브라우저입니다.
  • 나중에 만들어 붙이는 요소는 조각 안의 스타일이 안 닿습니다.
  • 함수를 부르는 테스트는 그 함수가 실제로 불리는지를 검사하지 않습니다.
  • 오류가 안 나는 결함은 회귀 테스트 말고는 막을 방법이 없습니다.

제일 오래 붙든 건 ①이었습니다. 로딩 표시가 멈춰 있으니 화면이 아직 요청도 안 보낸 줄 알았거든요. 실제로는 이미 다 받아서 그리는 중이었습니다. 정반대로 보고 있었습니다.


만든 것들