노트

디버깅 문제 정의 5단계

개발 문화#debugging · 연결된 개념 13개

쉽게 말하면

디버깅 문제 정의 5단계는 의사가 약부터 주지 않고 어디가 어떻게 아픈지, 원래 정상은 어떤지부터 묻는 순서와 비슷해요. 그래야 증상만 덮지 않고 진짜 원인을 고쳐요.

비유가 깨지는 곳 진료와 달리 버그는 가장 작은 조건으로 줄여 일부러 다시 일으킬 수 있어요. 차이를 만드는 원인 후보를 모두 적고, 한 번에 하나만 바꾸는 가설 검증으로 지워 가요.

버그를 만나면 바로 코드를 고치고 싶어진다. 하지만 무엇이 문제인지 정의하지 않고 고치면 증상만 덮게 된다. 다섯 단계로 문제를 정의하고 좁혀 가면 추측 대신 근거로 원인에 닿는다. 이 틀은 NEXTSTEP 「이펙티브 디버깅」 강의에서 다룬 내용을 정리한 것이다.

1. 문제 정의

지금 실제로 무슨 일이 일어나는지 사실로 적는다. "결제가 안 돼요"가 아니라 "쿠폰을 적용한 주문에서 결제 버튼을 누르면 500 응답이 온다". 에러 메시지는 처음부터 끝까지, 두 번 읽는다.

2. 올바른 동작 정의

원래 어떻게 동작해야 하는지 적는다. 기대가 분명하지 않으면 무엇이 버그인지도 분명하지 않다. 명세나 문서와 다르게 내가 기대하고 있었을 수도 있다.

3. 최소 재현 환경을 만들며 관찰

버그가 일어나는 가장 작은 조건(최소 재현, Minimal Reproduction)을 만든다. 줄여 가는 과정에서 버그가 사라지는 지점이 곧 단서다 → 최소 재현. 재현이 되면 실패하는 테스트로 고정해 둔다.

4. 차이를 만드는 원인 탐색

1과 2의 차이를 만들 수 있는 원인을 거르지 말고 모두 적는다. 한두 가지 그럴듯한 가능성에 매몰되지 않기 위해서다. 잘 되는 경우와 안 되는 경우를 비교한다. 입력, 환경, 버전, 최근 변경 → git bisect로 원인 커밋 찾기

5. 가설 설정과 검증

목록에서 하나를 골라 "X 때문이라면 Y를 하면 결과가 Z일 것이다"라고 가설(Hypothesis)을 세우고 확인한다. 질문은 20분 안에 답할 수 있을 만큼 작게 쪼갠다. 한 번에 하나만 바꾸고, 결과에 따라 목록을 지워 간다. 시도한 것과 결과를 기록해 두면 오래 걸리는 디버깅에서도 길을 잃지 않는다.

팁

  • 가정을 믿지 않는다. 확실해 보이는 전제에 어서션을 걸어 확인한다
  • 막히면 문제를 남에게 설명하듯 다시 정의해 본다 → 러버덕 디버깅
  • 고친 뒤에는 2단계에서 정의한 올바른 동작을 테스트로 남긴다 → 자가 테스트 코드

알고리즘 문제를 풀 때 문제를 먼저 정확히 이해하는 알고리즘 문제 풀이 접근법, 해결책보다 문제를 먼저 보는 문제 공간과 해결 공간와 같은 태도다. 더 많은 전략은 디버깅 포켓 가이드 (개요)에 있다.

출처: NEXTSTEP 「이펙티브 디버깅」

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 테스트 냄새

    테스트 코드나 테스트 습관에서 나는, 더 깊은 문제를 알리는 신호. 제라드 메스자로스의 xUnit 테스트 패턴 정리가 이름을 붙였다.

  • 코드 냄새

    당장 버그는 아니지만 이해나 변경 비용을 높이는 구조적 신호. 리팩터링을 언제 시작하고 멈출지에 정확한 공식은 없어서, 냄새라는 어휘로 직관을 공유한다.

보기 옵션