라이프스타일

버그 수정의 전체 과정

디버깅은 재현 가능한 증상에서 시작해 근거로 원인을 좁히고 수정 결과를 검증합니다. 입력, 단계, 기대와 실제 결과를 전달하세요.

읽는 데 약 14분 · 실습 25 분

작업 흐름을 설명하는 그림이며 제품 스크린샷이 아닙니다.
사진: Mokaair (© Mokaair)
전체 목차:Codex 학습 센터: 전체 튜토리얼 목차

실습 · Desktop / CLI / VS Code / JetBrains / cloud

먼저 읽을 글

이 글의 목차
  1. 목표와 준비
  2. 1단계: 결함 버전과 재현 절차 고정
  3. 2단계: 화면 없는 최소 재현
  4. 3단계: 최소 수정과 원인 설명 요청
  5. 4단계: 같은 증거로 회귀 검증
  6. 디버깅 습관, 복원과 전달

목표와 준비

이 단락의 학습 자료:

1단계: 결함 버전과 재현 절차 고정

broken 다섯 파일을 새 codex-bug-lab에 복사하고 원본을 남깁니다. Completed 조건이 반대이며 start의 미구현과 다릅니다. Get-Location/pwd로 위치를 확인하고 2통과1실패를 관찰합니다.

터미널: 기준 테스트 · sh
node --test core.test.mjs

로컬 미리 보기는 Windows에서 py -m http.server 4173 --bind 127.0.0.1, macOS/Linux에서 python3 -m http.server 4173 --bind 127.0.0.1을 실행합니다. URL을 열고 보존할 가상 데이터가 있으면 먼저 기록하세요. Reset practice data를 사용하고 All tasks에서 빈 목록을 확인한 뒤 Read, Build 순서로 추가하고 Read만 완료한 다음 Completed를 선택합니다. 기대값은 Read이고 결함 버전의 실제값은 Build입니다. 이 순서를 기록하세요. 데이터 초기화는 소스 파일을 복원하지 않습니다.

환경/시작/조작/기대/실제/증거를 적고 먼저 캐시 원인으로 단정하지 않습니다. 날짜/테스트는 관찰로 채웁니다. 화면이 다르면 실습/경로를 확인하고 글의 기대를 자신의 실측으로 삼지 않습니다.

문서 템플릿: 버그 보고서 · markdown
# Bug: Completed shows unfinished tasks
Environment/date: fill from this run
Fixture: broken copied to codex-bug-lab
Steps: reset practice data; add Read and Build; complete Read; select Completed.
Expected: Read only.
Observed: Build only, if reproduced.
Baseline: node --test core.test.mjs; fill actual result.
Scope: keep UI, storage format, ordering and tests unchanged.
Root cause: not confirmed yet.
Unperformed checks: list explicitly.

2단계: 화면 없는 최소 재현

다음 repro.mjs를 루트에 추가합니다. 완료/미완료를 직접 전달해 저장/DOM/캐시/네트워크를 거치지 않습니다. 다른 터미널에서 node repro.mjs를 실행하면 b를 표시하고 a 불일치로 0이 아닌 종료가 결함 증거입니다.

새 파일: repro.mjs · javascript
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";

const tasks = [
  { id: "a", title: "Read", completed: true },
  { id: "b", title: "Build", completed: false },
];
const actual = visibleTasks(tasks, "completed").map((task) => task.id);
console.log("Completed IDs:", JSON.stringify(actual));
assert.deepEqual(actual, ["a"]);
console.log("Reproduction passed.");
터미널: 최소 재현 · sh
node repro.mjs

브라우저 없이 틀리므로 이 결함 재현에 캐시/버튼은 필요 없습니다. 전체 UI 정상 증명은 아니지만 Completed부터 조사할 근거입니다. 미완료를 고르는 이유를 설명하게 하고 우연한 새로 고침 성공을 원인 발견으로 보지 않습니다.

동작 실패와 환경 실패 구분

node repro.mjs가 ERR_MODULE_NOT_FOUND를 표시하면 Completed 검증까지 도달하지 못한 상태입니다. 현재 폴더와 core.mjs 이름을 확인하세요. SyntaxError라면 코드를 빠짐없이 붙여 넣었는지 확인합니다. 프로그램이 로드되고 b를 출력한 뒤 a를 기대하는 검증에서 실패해야 이 결함이 재현된 것입니다. 첫 실행부터 통과해도 직접 고쳤다는 뜻은 아니며 expected를 복사했을 수 있습니다. 색이나 ‘실패’만 적지 말고 명령, 종료 코드, 실제 출력, 복사본 위치를 함께 남깁니다.

3단계: 최소 수정과 원인 설명 요청

데스크톱에서는 codex-bug-lab Codex 작업을 만들고 CLI에서는 해당 폴더를 확인한 뒤 codex를 실행합니다. 그다음 아래 제한 요청을 보내 기존 테스트와 repro.mjs를 고정합니다. 수정 뒤 오래된 결함 주석 한 줄은 제거해도 되지만 다른 함수 정리, UI 또는 프레임워크 변경은 하지 않습니다. 실패를 안 봤으면 먼저 확인하게 합니다.

Codex 프롬프트: 범위를 제한한 수정 · text
Fix the reproduced Completed-filter bug in this codex-bug-lab.
First read core.mjs, core.test.mjs and repro.mjs. Run node repro.mjs and node --test core.test.mjs to confirm the current failure.
Explain the predicate error using the actual a/b IDs. Modify only the completed predicate in core.mjs and remove its obsolete deliberate-bug comment. Do not change tests, repro.mjs, active behavior, storage or UI.
Rerun both commands, inspect the final diff and report actual results. Browser checks must be marked NOT RUN unless actually performed. Do not publish or deploy.

Completed가 Active와 같은 !task.completed를 쓰는 것이 원인입니다. 다음 줄만 바꾸고 Active의 !는 둡니다. 표시 이름 교환은 repro가 실패해 겉모습 변경과 동작 수정을 구분합니다.

참고 수정: Completed 분기 · javascript
if (filter === "completed") return tasks.filter((task) => task.completed);

4단계: 같은 증거로 회귀 검증

수정 후 repro는 ["a"]와 성공 문구/종료0, 기존3테스트 통과입니다. 같은 화면 순서로 Completed Read, Active Build, All 둘 다를 확인합니다. 같은 입력으로 원래 결함 해소를 먼저 증명하고 빈 목록/완료 해제를 추가합니다.

증거수정 전수정 후
최소 재현b, assertion 실패a, 종료0
기존 테스트2통과1실패3통과0실패
Completed 화면BuildRead
Active/All실제 결과 기록Build/둘 다 유지
미실행명시자동으로 통과 처리하지 않음

차이에서 addTask/decodeTasks/기댓값 불변을 확인합니다. 수정 주장뿐이면 명령/종료/실패 요약을 요청하고 실행 불가는 이유를 남깁니다. 명령 성공은 화면 확인 대신이 아니며 환경/URL과 함께 수행합니다.

완료 취소와 빈 목록 추가 확인

원래 재현이 통과한 뒤 아래 내용으로 regression.mjs를 만들고 node regression.mjs를 실행합니다. Completed의 a를 확인하고 a의 완료를 취소한 다음 Completed는 빈 목록, Active는 a/b인지 검증합니다. 원래 입력이 바뀌지 않았는지와 세 필터의 빈 목록도 확인합니다. 예상 결과는 Regression passed와 종료 코드 0입니다. 독립 검증 프로그램이므로 node --test core.test.mjs의 테스트 개수가 자동으로 늘지는 않습니다.

파일: regression.mjs · javascript
import assert from "node:assert/strict";
import { toggleTask, visibleTasks } from "./core.mjs";

const tasks = Object.freeze([
  Object.freeze({ id: "a", title: "Read", completed: true }),
  Object.freeze({ id: "b", title: "Build", completed: false }),
]);
const ids = (items, filter) => visibleTasks(items, filter).map((task) => task.id);
assert.deepEqual(ids(tasks, "completed"), ["a"]);
const changed = toggleTask(tasks, "a");
assert.deepEqual(ids(changed, "completed"), []);
assert.deepEqual(ids(changed, "active"), ["a", "b"]);
assert.deepEqual(ids(changed, "all"), ["a", "b"]);
assert.deepEqual(tasks.map((task) => task.completed), [true, false]);
for (const filter of ["all", "active", "completed"]) {
  assert.deepEqual(ids(Object.freeze([]), filter), []);
}
console.log("Regression passed.");
터미널: 경계 회귀 확인 · sh
node regression.mjs

원래 broken/core.mjs로 되돌리는 연습에서도 regression.mjs는 남깁니다. repro.mjs의 b와 일치하게 다시 0이 아닌 종료 코드로 실패해야 합니다. 테스트, 라벨, 저장 처리까지 바꿔 통과시켰다면 저장한 원본으로 돌아가 단일 수정부터 반복하고 에 폐기한 가설을 남깁니다. 완전한 회귀 검증에는 실제 화면과 새로고침 확인도 필요하며 하지 않은 항목은 미실행으로 둡니다.

디버깅 습관, 복원과 전달

검증 가능한 가설을 하나씩 바꾸고 시도/결과를 남겨 무효 수정 반복을 막습니다. 다른 원인 증거면 범위를 다시 좁히고 한 줄 실습에 억지로 맞추지 않습니다. 실제 타이밍/인증/네트워크 차이도 있으며 개인 데이터를 제거해 재현을 전달합니다.

보고/최소 재현/원인/차이/회귀 표를 전달합니다. 반복은 자신의 미리 보기 종료 후 broken/core.mjs만 복원하고 repro와 기존2통과1실패를 봅니다. 자세한 예는 로 갑니다. 그림1재현,2원인수정,3회귀이며 참고 검증과 각자의 Codex 실행을 구분합니다.

20. 버그 수정의 전체 과정 — 작업 흐름을 설명하는 그림이며 제품 스크린샷이 아닙니다. Reproduce → Fix → Regression
20. 버그 수정의 전체 과정 — 작업 흐름을 설명하는 그림이며 제품 스크린샷이 아닙니다. Reproduce → Fix → Regression · 사진: Mokaair (© Mokaair)
자세한 설명 보기

Reproduce to Fix to Regression

전체 목차

  • 라이프스타일

    Codex 학습 센터: 전체 튜토리얼 목차

    설치와 첫 작업부터 MD 지침과 고급 연동까지 60개 강의, 열 개 단원을 계획합니다. 수준, 환경, 목표, 명령으로 다음 글을 찾고 미게시 항목의 상태를 확인할 수 있습니다.

  • 라이프스타일

    Worktree와 작업 격리

    Worktree는 하나의 Git 저장소에 다른 브랜치의 작업 폴더를 만듭니다. 파일이 분리되어도 DB, 포트와 외부 서비스는 공유될 수 있습니다.

  • 라이프스타일

    실습: 작은 웹사이트 만들기

    brief.md에서 Small Steps 할 일 사이트를 계획하고 추가·완료·삭제·필터·로컬 저장을 구현합니다. HTML·CSS·데이터 함수·화면 이벤트·시험을 분리하고 Node와 브라우저로 검증한 뒤 재시작·복원 인계 기록을 남깁니다.

  • 라이프스타일

    사용량과 효율: 재작업 줄이기

    조건, 모델 선택, 시간, 결과를 기록해 불필요한 재시도와 과도한 문맥을 줄입니다.

최신 여행 소식·가이드

출처

라이프스타일