테스트, 디버깅, 리팩토링을 Codex에게 맡기기
앱은 '돌아간다'에서 끝나지 않는다
지금까지 우리는 Codex로 앱을 만들고, 화면을 다듬고, 기능을 붙이는 흐름을 익혔습니다. 하지만 앱 개발은 "일단 돌아간다"에서 끝나지 않습니다. 오히려 진짜 개발은 그다음부터 시작됩니다.
버튼을 눌렀더니 가끔만 저장이 안 된다거나, 로그인한 사용자 A의 데이터가 사용자 B에게 보이면 안 된다거나, 모바일에서는 카드 레이아웃이 깨지는 문제가 생깁니다. 기능을 하나 더 붙였더니 예전 기능이 망가지는 일도 흔합니다. 초보자에게 가장 무서운 순간은 바로 이때입니다. "어디서부터 봐야 하지?"라는 막막함이 밀려오니까요.
Codex의 진짜 가치는 새 코드를 처음 작성하는 데서만 나오지 않습니다. 코드를 읽고, 실패를 재현하고, 테스트를 추가하고, 최소한으로 고치고, 다시 검증하는 반복 작업에서 더 크게 드러납니다. OpenAI는 Codex를 코드 작성뿐 아니라 디버깅, 테스트, 리팩토링 같은 반복 개발 업무를 도와주는 코딩 에이전트로 설명합니다.1 이번 장에서는 앱을 "돌아가는 상태"에서 "믿고 고칠 수 있는 상태"로 끌어올리는 방법을 배웁니다.

초보자가 가장 먼저 바꿔야 할 습관
초보자는 에러가 나면 보통 터미널 로그 전체를 복사해서 Codex에게 붙여 넣습니다.
이거 왜 안 돼?
[엄청 긴 에러 로그 전체]이 방식이 항상 나쁜 것은 아닙니다. 하지만 로그가 길수록 Codex가 중요한 신호와 잡음을 함께 봅니다. 원인을 찾을 수도 있지만, 엉뚱한 부분을 의심할 가능성도 커집니다. 더 좋은 방법은 "문제 보고서"처럼 정리해서 주는 것입니다.
다음 버그를 분석해 줘. 바로 수정하지 말고, 먼저 원인 후보를 좁혀 줘.
상황:
- 할 일 관리 앱에서 새 할 일을 추가하면 목록에는 보이지만 새로고침 후 사라짐
재현 단계:
1. npm run dev 실행
2. 브라우저에서 /todos 접속
3. 입력창에 "우유 사기" 입력 후 추가 버튼 클릭
4. 목록에 항목이 표시됨
5. 브라우저 새로고침
기대 동작:
- 새로고침 후에도 "우유 사기"가 남아 있어야 함
실제 동작:
- 새로고침하면 방금 추가한 항목이 사라짐
실행한 명령어:
- npm run dev
- npm test는 아직 실행하지 않음
관련 에러 메시지:
- 브라우저 콘솔 에러 없음
- 터미널 에러 없음
영향 범위:
- 할 일 생성 기능
- 기존 할 일 표시 기능은 정상으로 보임
요청:
1. 가능한 원인을 3개 이하로 정리해 줘.
2. 어떤 파일을 확인해야 하는지 알려 줘.
3. 수정 전에 실패하는 테스트를 먼저 추가하는 계획을 세워 줘.핵심은 "로그를 던지는 것"이 아니라 "조사할 수 있는 단서"를 주는 것입니다. Codex에게 원인을 좁혀 달라고 요청하면, 바로 코드를 고치기 전에 현재 앱의 구조와 데이터 흐름을 먼저 읽게 만들 수 있습니다. 공식 베스트 프랙티스에서도 Codex를 더 잘 쓰려면 계획, 검증, 명확한 지시를 함께 사용하는 습관이 중요하다고 안내합니다.2
좋은 디버깅 요청은 의사에게 증상을 설명하듯 쓴다
버그를 설명할 때는 병원에 갔다고 상상해 보세요. "몸이 이상해요"라고만 말하면 의사가 바로 원인을 알기 어렵습니다. 언제부터 아팠는지, 어떤 행동을 하면 심해지는지, 열이 있는지, 먹은 약은 무엇인지 말해야 합니다.
코드도 같습니다. Codex에게 버그를 맡길 때는 다음 정보가 있으면 훨씬 안정적입니다.
관련 에러 메시지: 전체 로그보다 핵심 에러 줄과 스택 트레이스의 시작 부분이 중요합니다.
재현 단계: Codex가 같은 문제를 다시 만들 수 있어야 합니다.
기대 동작과 실제 동작: 무엇이 맞고 무엇이 틀렸는지 기준을 줍니다.
실행한 명령어:
npm test,npm run build,npm run dev처럼 이미 해 본 일을 알려 줍니다.영향 범위: 로그인, 결제, 목록 조회, 특정 화면처럼 문제가 퍼진 범위를 좁힙니다.
예를 들어 날씨 대시보드 앱에서 API 키 문제인지, 날짜 포맷 문제인지, 렌더링 문제인지 헷갈릴 수 있습니다. 이때는 이렇게 요청할 수 있습니다.
날씨 대시보드의 /weather 화면에서 도시를 검색하면 로딩 후 빈 카드만 표시됩니다.
바로 수정하지 말고 다음 순서로 진행해 줘.
1. package.json과 src/app 또는 src/pages 구조를 확인해 현재 프레임워크를 파악해 줘.
2. 날씨 API 호출 코드와 화면 렌더링 코드를 찾아 데이터 흐름을 설명해 줘.
3. 문제 원인을 API 응답, 상태 관리, 렌더링 조건 중 어디로 볼 수 있는지 근거를 들어 좁혀 줘.
4. 가능하면 실패를 재현하는 테스트 또는 작은 재현 스크립트를 먼저 추가해 줘.
5. 테스트 실패를 확인한 뒤 최소 변경으로 수정해 줘.여기서 중요한 문장은 "바로 수정하지 말고"입니다. Codex는 유능하지만, 너무 빨리 고치라고 하면 원인 추측만으로 코드를 바꿀 수 있습니다. 초보자는 "일단 고쳐 줘"보다 "먼저 증명해 줘"라고 말하는 습관을 들여야 합니다.
테스트는 Codex에게 맡기되, 도구 선택은 확인하게 하자
테스트 도구에는 여러 종류가 있습니다. 자바스크립트와 타입스크립트 프로젝트에서는 Jest, Vitest, Playwright 같은 이름을 자주 만납니다. 처음 보면 전부 비슷해 보이지만 역할이 조금 다릅니다.
Jest와 Vitest는 보통 함수, 컴포넌트, API 로직을 빠르게 검증하는 데 많이 씁니다. Playwright는 실제 브라우저를 띄워 사용자가 클릭하고 입력하는 흐름을 검사하는 E2E 테스트에 자주 사용합니다. E2E는 "End-to-End"의 줄임말로, 사용자가 앱을 처음부터 끝까지 쓰는 흐름을 테스트한다는 뜻입니다.
초보자가 흔히 하는 실수는 "Playwright 테스트 만들어 줘"처럼 도구를 먼저 정해 버리는 것입니다. 물론 화면 흐름 검증이 목적이라면 좋습니다. 하지만 단순한 날짜 포맷 함수 하나를 확인하려고 Playwright를 붙이면 너무 무겁습니다. 반대로 로그인부터 프로젝트 생성까지 실제 사용자 흐름을 확인해야 하는데 단위 테스트만 있으면 부족합니다.
따라서 Codex에게 먼저 프로젝트를 살피게 하세요.
이 프로젝트에 테스트를 추가하고 싶어.
먼저 package.json, 프레임워크, 폴더 구조를 확인한 뒤 현재 프로젝트에 이미 설정된 테스트 도구가 있는지 조사해 줘.
그다음 아래 기준으로 첫 테스트 전략을 제안해 줘.
- 이미 Jest/Vitest/Playwright 중 하나가 있으면 기존 도구를 우선 사용
- 새 도구 설치가 필요하면 이유와 설치 명령어를 먼저 설명
- 첫 테스트는 가장 작은 범위로 시작
- 테스트 추가 전에는 어떤 동작을 검증할지 표로 정리
- 바로 파일을 수정하지 말고 계획부터 보여 줘이 요청의 장점은 Codex가 무작정 새 패키지를 설치하지 않게 만든다는 점입니다. 프로젝트에 이미 Vitest가 있는데 Jest를 새로 설치하면 설정이 복잡해지고 중복이 생길 수 있습니다. Next.js 프로젝트, Vite 프로젝트, Express API 서버, React Native 앱은 테스트 설정이 다를 수 있으므로 먼저 확인해야 합니다.
단위 테스트, 통합 테스트, E2E 테스트 쉽게 구분하기
테스트라는 단어 하나로 모든 검증을 뭉뚱그리면 헷갈립니다. 초보자는 세 가지만 구분해도 충분합니다.
단위 테스트는 가장 작은 조각을 확인합니다. 예를 들어 formatTemperature(21.4)가 21°C를 반환하는지, 비밀번호 검증 함수가 8자 미만 입력을 거절하는지 확인합니다. 빠르고 가볍지만, 실제 화면 전체가 잘 동작하는지는 보장하지 않습니다.
통합 테스트는 여러 조각이 함께 맞물리는지 봅니다. 예를 들어 로그인 API가 요청을 받고, 데이터베이스에서 사용자를 찾고, 세션 쿠키를 설정하는 흐름을 확인합니다. 단위 테스트보다 조금 무겁지만 실제 버그를 더 잘 잡아냅니다.
E2E 테스트는 사용자 입장에서 앱을 검증합니다. 브라우저를 열고, 이메일을 입력하고, 버튼을 누르고, 대시보드로 이동했는지 확인합니다. 가장 현실적이지만 실행 시간이 길고 설정이 복잡할 수 있습니다.
Codex에게는 이렇게 판단을 맡길 수 있습니다.
현재 수정하려는 기능은 "미니 SaaS에서 프로젝트 생성 후 목록에 즉시 표시되는 동작"이야.
이 기능에 가장 적합한 첫 테스트가 단위 테스트, 통합 테스트, E2E 테스트 중 무엇인지 판단해 줘.
판단 근거도 설명해 줘.
조건:
- 초보자가 유지보수하기 쉬워야 함
- 테스트 실행 시간이 너무 길지 않아야 함
- 기존 테스트 도구가 있으면 그것을 우선 사용
- 첫 번째 테스트는 1개만 추가좋은 Codex는 여기서 "상태 업데이트 함수만 문제라면 단위 테스트", "API와 DB 연결이 중요하면 통합 테스트", "브라우저에서 생성 후 이동까지 확인해야 하면 E2E 테스트"처럼 선택지를 좁혀 줄 것입니다.
실패하는 테스트를 먼저 만들면 버그 수정이 쉬워진다
버그 수정에서 가장 안전한 흐름은 다음과 같습니다. 먼저 버그를 재현하는 테스트를 추가합니다. 그 테스트가 실패하는 것을 확인합니다. 그다음 코드를 최소한으로 고칩니다. 마지막으로 같은 테스트가 통과하는지 확인합니다.
이 방식은 처음에는 느려 보입니다. 하지만 실제로는 시간을 아낍니다. 테스트 없이 고치면 "정말 고쳐졌는지" 매번 손으로 확인해야 합니다. 더 나쁜 경우, 고친 줄 알았는데 다른 기능이 망가질 수 있습니다.
예를 들어 할 일 관리 앱에서 완료 체크가 새로고침 후 풀리는 문제가 있다고 합시다. Codex에게 이렇게 요청합니다.
버그: 할 일을 완료 처리한 뒤 새로고침하면 완료 상태가 다시 false로 돌아갑니다.
수정 전에 테스트를 먼저 추가해 줘.
진행 순서:
1. 관련 코드 경로를 찾아 완료 상태 저장 흐름을 설명
2. 이 버그를 재현하는 테스트를 1개 추가
3. 테스트 명령어를 실행해서 실패를 확인
4. 실패 원인을 설명
5. 최소 변경으로 수정
6. 같은 테스트를 다시 실행해서 통과 여부 확인
7. 변경 파일과 이유를 요약
제약:
- UI 디자인은 변경하지 말 것
- 데이터 모델 필드명은 가능하면 유지
- 새 라이브러리는 설치하지 말 것이 요청은 Codex를 단순한 코드 생성기가 아니라 "검증 루프를 도는 동료 개발자"처럼 사용하게 만듭니다. Codex가 코드를 읽고 명령을 실행할 수 있는 환경에서는 테스트, 린트, 타입 체크 같은 검증 명령까지 함께 돌리게 하는 것이 좋습니다. Codex App은 여러 스레드와 worktree, Git 기능을 함께 제공해 변경 사항을 분리하고 검토하는 흐름에 적합합니다.3
실패 로그를 붙여 넣을 때의 좋은 예와 나쁜 예
테스트가 실패하면 당황하지 마세요. 실패한 테스트는 적이 아니라 지도입니다. 어디가 잘못됐는지 알려 주는 표지판입니다.
나쁜 요청은 이렇습니다.
테스트 깨졌어. 고쳐.
[전체 로그 500줄]좋은 요청은 이렇습니다.
방금 Codex가 추가한 테스트를 실행했더니 실패했습니다.
실행한 명령어:
npm test -- todos
실패한 테스트:
Todo completion persistence > keeps completed state after reload
핵심 에러:
Expected: true
Received: false
관련 파일로 보이는 곳:
- src/features/todos/todoStore.ts
- src/features/todos/TodoList.tsx
- src/features/todos/todoStore.test.ts
요청:
1. 이 실패가 테스트 기대값 문제인지 실제 구현 문제인지 판단해 줘.
2. 판단 근거를 코드 경로 기준으로 설명해 줘.
3. 테스트가 타당하다면 구현을 최소 수정해 줘.
4. 수정 후 같은 테스트 명령어를 다시 실행해 줘.여기서 "테스트 기대값 문제인지 실제 구현 문제인지"를 물어보는 것이 중요합니다. 모든 실패 테스트가 올바른 테스트는 아닙니다. Codex가 만든 테스트도 요구사항을 오해할 수 있습니다. 테스트가 틀렸다면 테스트를 고쳐야 하고, 구현이 틀렸다면 구현을 고쳐야 합니다.
검증 명령어를 Codex에게 직접 실행하게 하기
Codex에게 코드 수정을 맡길 때 "수정해 줘"에서 끝내면 아쉽습니다. 반드시 검증까지 요청하세요.
대표적인 검증 명령은 다음과 같습니다.
npm test: 테스트 실행npm run lint: 코드 스타일과 잠재 오류 검사npm run typecheck: TypeScript 타입 검사npm run build: 배포 가능한 빌드 확인npx playwright test: 브라우저 기반 E2E 테스트 실행
프로젝트마다 명령어가 다를 수 있으니, AGENTS.md에 공통 명령을 적어 두면 좋습니다.
## Validation
Before reporting a task as complete, run the relevant commands:
- npm run lint
- npm run typecheck
- npm test
- npm run build
For UI flow changes, run:
- npx playwright test그다음 Codex에게 이렇게 말합니다.
변경 후 완료 보고를 하기 전에 package.json을 확인해서 이 프로젝트의 검증 명령을 찾아 실행해 줘.
필수:
1. 수정한 기능과 직접 관련된 테스트 실행
2. 가능하면 lint와 typecheck 실행
3. 실패하면 실패 원인을 요약하고 바로 추가 수정 계획 제시
4. 통과하면 실행한 명령어와 결과를 짧게 보고Codex CLI를 사용한다면 로컬 프로젝트에서 직접 코드를 읽고 수정하며 명령을 실행하는 흐름을 만들 수 있습니다. 공식 저장소에서는 Codex CLI가 로컬 컴퓨터에서 실행되는 코딩 에이전트이며 npm 또는 Homebrew로 설치할 수 있다고 안내합니다.4
실전 예제 1: 로그인 버그를 테스트로 잡기
미니 SaaS 앱에서 이런 문제가 생겼다고 해 봅시다.
"로그아웃한 상태에서 /dashboard에 직접 접속하면 로그인 페이지로 이동해야 하는데, 빈 대시보드가 잠깐 보인다."
초보자는 이 문제를 보고 라우터 코드부터 뒤지기 쉽습니다. 하지만 더 좋은 흐름은 재현 조건을 테스트로 고정하는 것입니다.
미니 SaaS 앱의 인증 보호 흐름을 점검해 줘.
버그:
로그아웃 상태에서 /dashboard에 직접 접속하면 로그인 페이지로 리다이렉트되어야 하는데, 빈 대시보드가 잠깐 표시됩니다.
먼저 다음을 확인해 줘.
1. 현재 인증 처리가 서버 컴포넌트, 미들웨어, 클라이언트 훅 중 어디서 이루어지는지 조사
2. 이 동작을 검증하기에 적합한 테스트 종류를 제안
3. 가능하면 Playwright E2E 테스트 1개로 재현
4. 테스트 실패를 확인한 뒤 최소 수정
5. 수정 후 같은 Playwright 테스트 재실행
제약:
- 로그인 UI 디자인은 변경하지 말 것
- 인증 라이브러리 설정을 크게 바꾸지 말 것
- 리다이렉트 경로는 /login 유지이런 버그는 단위 테스트보다 E2E 테스트가 잘 맞을 가능성이 큽니다. 사용자가 실제로 URL을 입력하고 페이지 이동을 경험하는 문제이기 때문입니다. Codex가 Playwright를 설정해야 한다면, 먼저 package.json을 보고 이미 설치되어 있는지 확인하게 하세요. 없다면 설치 이유와 변경 파일을 설명하게 합니다.
변경 후에는 다음과 같은 보고를 요구합니다.
마지막에 아래 형식으로 요약해 줘.
- 원인:
- 추가한 테스트:
- 수정한 파일:
- 실행한 명령어:
- 통과/실패 결과:
- 남은 위험:이 형식은 나중에 커밋 메시지나 PR 설명을 쓸 때도 그대로 활용할 수 있습니다.
실전 예제 2: 날씨 대시보드의 날짜 포맷 테스트하기
날씨 앱에서 "오늘", "내일", "수요일" 같은 날짜 라벨이 틀리게 나온다고 합시다. 이 문제는 브라우저 전체를 띄우지 않아도 될 수 있습니다. 날짜를 라벨로 바꾸는 함수가 따로 있다면 단위 테스트가 더 좋습니다.
날씨 대시보드에서 예보 카드의 날짜 라벨이 하루씩 밀리는 문제가 있습니다.
먼저 날짜 포맷 관련 함수나 유틸 파일을 찾아 줘.
그 함수가 있다면 단위 테스트를 추가해 다음 케이스를 검증해 줘.
테스트 케이스:
- 오늘 날짜는 "오늘"로 표시
- 오늘 + 1일은 "내일"로 표시
- 오늘 + 2일 이후는 요일로 표시
- 시간대 차이 때문에 날짜가 밀리지 않아야 함
진행 방식:
1. 테스트 도구 확인
2. 테스트 파일 추가
3. 실패 확인
4. 최소 수정
5. 관련 테스트 재실행
제약:
- UI 컴포넌트 구조는 바꾸지 말 것
- 날짜 라이브러리를 새로 설치하지 말 것이 요청은 범위가 작고 명확합니다. Codex가 건드릴 파일도 자연스럽게 제한됩니다. 리팩토링이나 버그 수정은 이렇게 작게 나눌수록 성공률이 높아집니다.
리팩토링은 "전체 코드 정리"라고 맡기지 않는다
리팩토링은 겉으로 보이는 동작은 유지하면서 내부 구조를 개선하는 작업입니다. 예를 들어 중복 코드를 함수로 빼거나, 너무 긴 컴포넌트를 작은 컴포넌트로 나누거나, 에러 처리 방식을 통일하는 일이 리팩토링입니다.
하지만 Codex에게 이렇게 말하면 위험합니다.
전체 코드 깔끔하게 정리해 줘.범위가 너무 넓습니다. Codex가 파일을 많이 바꾸고, 이름을 대거 변경하고, 예상치 못한 동작 변화까지 만들 수 있습니다. 리팩토링은 반드시 대상, 목표, 제약, 완료 조건을 줘야 합니다.
좋은 요청은 다음과 같습니다.
src/components/PricingCard.tsx를 리팩토링해 줘.
목표:
- 중복된 버튼 렌더링 로직을 작은 내부 컴포넌트로 추출
- props 타입을 명확히 정리
- 화면 동작과 스타일은 그대로 유지
제약:
- 파일 범위는 src/components/PricingCard.tsx로 제한
- CSS 클래스 이름 변경 금지
- public API 변경 금지
- 새 라이브러리 설치 금지
완료 조건:
- npm run typecheck 통과
- 관련 스냅샷이나 컴포넌트 테스트가 있으면 실행
- 변경 전후 동작 차이가 없음을 요약
먼저 계획을 설명하고, 내가 승인하면 수정해 줘.이 요청은 안전합니다. Codex가 무엇을 해야 하고 무엇을 하지 말아야 하는지 알 수 있기 때문입니다.
리팩토링 유형별 프롬프트 예시
리팩토링은 종류가 다양합니다. 초보자는 아래 예시를 복사해서 프로젝트 상황에 맞게 바꿔 써도 좋습니다.
중복 컴포넌트 추출
src/features/todos/TodoList.tsx와 src/features/todos/CompletedTodoList.tsx에 비슷한 카드 렌더링 코드가 반복됩니다.
목표:
- 중복된 카드 UI를 TodoItemCard 컴포넌트로 추출
- 기존 화면 동작과 스타일 유지
- props 타입 명확화
제약:
- 할 일 생성/수정/삭제 로직은 변경하지 말 것
- CSS 클래스 이름은 가능한 유지
- 한 번에 너무 많은 파일을 바꾸지 말 것
완료 조건:
- 관련 테스트 실행
- npm run typecheck 실행
- 변경한 파일과 추출한 이유 요약
먼저 어떤 중복을 발견했는지 설명하고 계획을 제시해 줘.타입 안정성 강화
src/lib/api.ts에서 any 타입 사용을 줄이고 싶습니다.
목표:
- API 응답 타입을 명시
- any를 가능한 구체 타입으로 교체
- 런타임 동작은 변경하지 않음
제약:
- API 호출 방식 변경 금지
- 백엔드 응답 필드명 변경 금지
- 타입 오류를 없애기 위해 억지 타입 단언을 남발하지 말 것
완료 조건:
- npm run typecheck 통과
- 변경 전후 동작 차이 없음
- 남아 있는 any가 있다면 이유 설명에러 처리 방식 통합
src/app/api 아래 API 라우트들의 에러 응답 형식이 제각각입니다.
목표:
- 공통 에러 응답 헬퍼를 만들어 형식을 통일
- 기존 성공 응답 구조는 유지
- 클라이언트가 의존하는 status code는 바꾸지 않음
제약:
- 인증/권한 로직 변경 금지
- 데이터베이스 쿼리 조건 변경 금지
- 한 번에 모든 라우트를 바꾸지 말고 대표 라우트 2개만 먼저 적용
완료 조건:
- 대표 라우트 테스트 추가 또는 기존 테스트 수정
- npm test 실행
- 적용 전후 에러 응답 예시 요약긴 함수 분리
src/features/weather/buildForecastViewModel.ts 함수가 너무 길어 읽기 어렵습니다.
목표:
- 날짜 라벨 생성, 온도 표시, 경고 메시지 생성을 작은 순수 함수로 분리
- 외부에서 호출하는 함수 시그니처는 유지
- 기존 테스트가 있다면 그대로 통과
제약:
- 로직 결과 변경 금지
- 새 의존성 추가 금지
- 파일 이동은 하지 말 것
완료 조건:
- 기존 테스트 통과
- 새로 분리한 함수 이름과 역할 요약
- 리팩토링으로 동작이 바뀌지 않았다는 근거 제시이런 식으로 요청하면 Codex가 "멋대로 대공사"를 할 가능성이 크게 줄어듭니다.
변경 전 계획, 변경 후 검증
Codex와 안전하게 협업하는 기본 리듬은 단순합니다.
계획 → 수정 → 검증 → 리뷰 → 승인처음부터 파일을 바꾸게 하지 말고, 먼저 계획을 설명하게 하세요.
아직 코드를 수정하지 말고 리팩토링 계획만 작성해 줘.
포함할 내용:
- 수정 대상 파일
- 바꾸려는 구조
- 동작 변경 가능성이 있는 위험 지점
- 실행할 검증 명령어
- 예상 diff 규모계획이 납득되면 그때 수정하게 합니다.
계획대로 진행해 줘.
단, 예상보다 변경 파일이 늘어나면 중단하고 먼저 보고해 줘.수정 후에는 반드시 검증을 요구합니다.
변경이 끝났으면 다음을 실행해 줘.
1. npm run typecheck
2. npm run lint
3. npm test
4. 관련 UI 흐름이 있으면 npx playwright test로 해당 스펙만 실행
실패한 명령이 있으면 원인과 다음 조치를 요약하고,
바로 큰 수정에 들어가지 말고 계획을 먼저 제시해 줘.이 루프를 지키면 Codex가 만든 변경을 훨씬 더 안심하고 검토할 수 있습니다.
Codex에게 두 번째 눈을 맡기기
코드를 고친 Codex에게 바로 "좋아, 끝"이라고 하면 안 됩니다. 사람 개발자도 자기 코드의 실수를 놓칩니다. Codex도 마찬가지입니다. 그래서 변경 후에는 리뷰 단계를 따로 두는 것이 좋습니다.
일부 Codex CLI와 워크플로에서는 현재 변경 사항을 검토하는 리뷰 기능이나 /review 같은 명령을 활용할 수 있습니다. 명령 이름은 버전에 따라 달라질 수 있으므로, 현재 환경의 도움말을 확인하세요.5 명령이 없더라도 일반 프롬프트로 충분히 리뷰를 요청할 수 있습니다.
현재 git diff를 기준으로 리뷰해 줘.
특히 다음 관점으로 봐 줘.
1. 버그 가능성
2. 보안 문제
3. 성능 저하
4. 유지보수성 악화
5. 테스트 누락
리뷰 결과는 심각도 순으로 정리하고,
실제로 수정이 필요한 항목과 참고 의견을 구분해 줘.
수정은 아직 하지 마.특히 앞 장에서 만든 로그인과 CRUD가 있는 미니 SaaS 같은 프로젝트에서는 ownerId 검사 누락이 치명적인 버그가 될 수 있습니다. 이럴 때 Codex 리뷰를 보안 관점으로 좁혀 요청하면 효과가 좋습니다.
현재 git diff를 리뷰해 줘.
관점:
- 로그인하지 않은 사용자가 보호된 데이터에 접근할 수 있는지
- ownerId 검사가 누락된 CRUD API가 있는지
- 실패 시 사용자에게 너무 기술적인 에러가 노출되는지
- 불필요한 리렌더링이나 중복 API 호출이 생겼는지
- 테스트가 변경된 동작을 충분히 덮는지
수정은 바로 하지 말고, 먼저 리뷰 결과만 제시해 줘.Codex 리뷰 결과를 그대로 믿지 않는 법
Codex가 리뷰에서 "문제없음"이라고 해도 최종 승인자는 사람입니다. 반대로 Codex가 지적한 모든 항목을 반드시 고쳐야 하는 것도 아닙니다. 리뷰 결과는 "검토 후보 목록"입니다.
리뷰 후에는 이렇게 다시 요청하세요.
방금 리뷰 결과 중 실제 수정이 필요한 항목만 골라 줘.
각 항목에 대해 다음을 표시해 줘.
- 반드시 수정해야 하는 이유
- 수정하지 않아도 되는 경우
- 수정 난이도
- 필요한 테스트
그다음 가장 안전한 1개 항목만 먼저 수정하는 계획을 세워 줘.이렇게 하면 Codex가 제안한 개선 사항을 한꺼번에 적용하지 않고, 위험이 큰 것부터 차근차근 처리할 수 있습니다. AI 코드 리뷰의 목적은 사람의 판단을 없애는 것이 아니라, 사람이 놓칠 수 있는 부분을 더 빨리 보게 만드는 것입니다.
실전 예제 3: CRUD API 리팩토링 후 보안 리뷰하기
미니 SaaS에서 프로젝트와 메모 CRUD API를 만들었다고 해 봅시다. 기능은 잘 동작합니다. 하지만 코드가 반복되고 에러 응답도 제각각입니다. 이제 리팩토링을 하고 싶습니다.
먼저 리팩토링 요청을 좁힙니다.
src/app/api/projects 아래 CRUD API를 리팩토링하고 싶습니다.
목표:
- 반복되는 ownerId 검사를 헬퍼 함수로 분리
- 에러 응답 형식을 통일
- 기존 API 경로와 응답 status는 유지
제약:
- 인증 방식 변경 금지
- 데이터베이스 스키마 변경 금지
- 한 번에 모든 파일을 바꾸지 말고 projects 라우트부터 적용
- ownerId 검사를 절대 제거하지 말 것
완료 조건:
- 프로젝트 목록/상세/생성/수정/삭제 테스트 통과
- npm run typecheck 통과
- 변경 후 diff 리뷰 수행
먼저 계획만 제시해 줘.수정이 끝나면 리뷰를 별도로 요청합니다.
현재 diff를 보안 관점으로 리뷰해 줘.
특히 다음을 확인해 줘.
1. 모든 조회/수정/삭제에서 ownerId 또는 프로젝트 소유권 검사가 유지되는지
2. 다른 사용자의 프로젝트 ID를 알 때 접근 가능한 경로가 생겼는지
3. 에러 메시지에 내부 정보가 과도하게 노출되는지
4. 테스트가 권한 실패 케이스를 포함하는지
수정하지 말고 리뷰 결과만 먼저 보여 줘.리뷰 결과에서 실제 문제가 나오면, 다시 테스트부터 추가하게 합니다.
리뷰에서 지적한 ownerId 누락 가능성을 재현하는 실패 테스트를 먼저 추가해 줘.
테스트가 실패하는 것을 확인한 뒤 최소 수정으로 막아 줘.
수정 후 권한 실패 테스트와 기존 CRUD 테스트를 다시 실행해 줘.이 흐름은 실무에서도 매우 중요합니다. 보안 버그는 "왠지 막았을 것 같다"로 끝내면 안 됩니다. 실패 테스트로 뚫리는 길을 먼저 보여 주고, 수정 후 막혔음을 확인해야 합니다.
실패했을 때 Codex에게 다음 조치를 이어서 맡기기
검증 명령이 실패하면 Codex가 멈추거나 장황하게 사과할 때가 있습니다. 이때는 감정적인 답변보다 다음 행동을 요구하세요.
테스트가 실패한 상태에서 멈추지 말고 다음 형식으로 정리해 줘.
1. 실패한 명령어
2. 실패한 테스트 이름
3. 핵심 에러 메시지 3줄 이내
4. 가장 가능성 높은 원인
5. 수정 후보 2개
6. 더 안전한 수정안 추천
7. 수정 전에 추가로 확인할 파일
아직 수정하지 말고 분석만 해 줘.분석이 괜찮으면 수정하게 합니다.
추천한 더 안전한 수정안으로 진행해 줘.
단, 변경 파일은 최소화하고 테스트 기대값을 억지로 낮추지 마.
수정 후 실패했던 명령어를 다시 실행해 줘."테스트 기대값을 억지로 낮추지 마"라는 문장이 중요합니다. 테스트를 통과시키는 가장 나쁜 방법은 올바른 기대값을 틀린 구현에 맞춰 바꾸는 것입니다. Codex가 그런 방향으로 가는지 항상 살펴야 합니다.
App, CLI, IDE에서의 역할 나누기
테스트와 리팩토링은 어느 Codex 화면에서 해도 됩니다. 다만 각 도구의 장점이 조금 다릅니다.
CLI는 빠르게 명령을 실행하고 로그를 확인하는 데 좋습니다. npm test, npm run build, git diff 같은 명령 중심 작업에 잘 맞습니다. IDE 확장은 열린 파일과 선택한 코드 맥락을 보며 작은 리팩토링을 할 때 편합니다. App은 여러 작업을 스레드와 worktree로 나누고, diff를 검토하고, Git 흐름까지 이어갈 때 강합니다.
예를 들어 다음처럼 나눌 수 있습니다.
CLI: 실패한 테스트 분석, 빠른 단위 테스트 추가, 타입 오류 수정
IDE: 특정 컴포넌트 리팩토링, 선택한 함수 설명, 작은 코드 정리
App: 큰 리팩토링 후보 실험, 병렬 버그 수정, diff 리뷰와 커밋 준비
중요한 것은 어디서 하든 같은 원칙을 지키는 것입니다. 작은 범위로 요청하고, 변경 전 계획을 받고, 변경 후 검증하고, diff를 리뷰합니다.
초보자를 위한 테스트 추가 첫날 루틴
테스트가 하나도 없는 프로젝트라면 어디서부터 시작해야 할까요? 모든 기능에 테스트를 붙이겠다고 마음먹으면 금방 지칩니다. 첫날에는 딱 하나만 목표로 잡으세요.
가장 추천하는 첫 테스트는 "최근에 고친 버그" 또는 "앞으로 자주 바꿀 핵심 로직"입니다. 이미 문제가 있었던 곳은 다시 깨질 가능성이 높고, 자주 바꿀 곳은 테스트의 효과가 큽니다.
Codex에게 이렇게 요청해 보세요.
이 프로젝트에는 테스트가 거의 없습니다.
초보자가 시작하기 좋은 첫 테스트 1개를 추천해 줘.
조건:
- 설정이 너무 복잡하지 않아야 함
- 실행 시간이 짧아야 함
- 실제 버그 예방 효과가 있어야 함
- package.json과 폴더 구조를 먼저 확인할 것
추천 후에는 다음을 제시해 줘.
1. 왜 이 테스트가 첫 테스트로 적합한지
2. 어떤 도구를 쓸지
3. 어떤 파일을 만들지
4. 실행 명령어
5. 성공 기준
아직 파일은 수정하지 마.테스트는 양보다 시작이 중요합니다. 테스트 100개를 한 번에 만들려 하지 말고, 신뢰할 수 있는 테스트 1개를 추가하는 경험부터 쌓으세요.
커밋 전 최종 점검 프롬프트
테스트와 리팩토링이 끝났다면 커밋 전에 마지막 점검을 합니다.
커밋 전에 현재 변경 사항을 최종 점검해 줘.
확인할 것:
1. git diff 요약
2. 의도하지 않은 파일 변경 여부
3. 디버그 로그나 임시 주석이 남았는지
4. 테스트/lint/typecheck 실행 결과
5. 보안상 민감한 값이 포함되었는지
6. 커밋 메시지 제안
수정이 필요한 항목이 있으면 바로 수정하지 말고 먼저 목록으로 보여 줘.이 프롬프트는 초보자에게 특히 유용합니다. AI와 작업하다 보면 생각보다 많은 파일이 바뀌어 있을 수 있습니다. 커밋 전에는 항상 diff를 요약하게 하고, 직접 눈으로 확인해야 합니다.
이 장의 핵심 정리
Codex는 코드를 처음 만드는 도구이기도 하지만, 더 큰 가치는 고치고 검증하는 반복 작업에서 나옵니다. 버그가 생겼을 때는 로그 전체를 던지지 말고, 재현 단계와 기대 동작, 실제 동작, 실행한 명령어, 영향 범위를 함께 정리하세요.
테스트 도구는 Codex가 프로젝트 구조를 확인한 뒤 선택하게 만드는 편이 안전합니다. Jest, Vitest, Playwright 중 무엇이든 "현재 기능에 맞는 가장 작은 첫 테스트"부터 시작하면 됩니다. 버그 수정은 바로 고치기보다 실패하는 테스트나 재현 스크립트를 먼저 추가하고, 실패를 확인한 뒤 최소 변경으로 고쳐야 합니다.
리팩토링은 "전체 정리"처럼 넓게 맡기지 마세요. 대상 파일, 목표, 제약, 완료 조건을 명확히 지정해야 합니다. 변경 전에는 계획을 받고, 변경 후에는 npm test, lint, typecheck, Playwright 같은 검증 명령을 실행하게 하세요. 마지막으로 코드 리뷰 기능이나 일반 리뷰 프롬프트를 활용해 diff 기준으로 버그, 보안, 성능, 유지보수성 문제를 점검하세요.
앱이 돌아가는 것은 출발점입니다. 테스트가 있고, 디버깅 경로가 있고, 리팩토링해도 무섭지 않은 상태가 되어야 진짜로 유지보수 가능한 앱이 됩니다. 이제 Codex를 "코드를 써 주는 도구"가 아니라 "앱을 계속 건강하게 유지하는 동료"로 다룰 준비가 되었습니다.
참고
2Best practices - Codex | OpenAI Developers
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.