실행과 완료의 차이
75분 안팎
학습 목표
실행만 성공하는 가짜 앱을 보고 요구사항별 완료 증거 표를 작성합니다.
개념
실행 기록은 완료 증거의 일부입니다
신입이 AI의 “완성했습니다”라는 보고를 받으면 바로 다음 일을 시작하고 싶어집니다. 하지만 실행이 끝났다는 사실과 사용자의 요구가 충족되었다는 사실은 다릅니다. 오류 없이 종료하는 프로그램은 제목을 무시하고 같은 값을 반환할 수도 있습니다. 이 레슨은 가짜 앱의 실행 결과를 요구사항별로 비교하여 무엇이 통과했고 무엇이 실패했으며 무엇을 아직 확인하지 않았는지 기록하는 방법을 익힙니다.
실행 성공은 명령이 시작되어 종료되고 실행 환경 오류가 없었다는 증거입니다. 계약 충족은 주어진 초기 상태와 입력에서 결과와 이후 상태가 기대와 일치했다는 증거입니다. 범위 준수는 관련 없는 기능이나 파일이 추가되지 않았다는 검토 증거입니다. 이 세 질문을 하나의 “정상”으로 합치면 어떤 확인이 빠졌는지 보이지 않습니다. 같은 실행 기록이 있어도 요구사항별 판단은 서로 다를 수 있습니다.
여기서 보는 가짜 생성 함수는 언제나 번호 1과 입력 제목을 반환하며 done을 true로 만듭니다. Python 실행은 정상적으로 끝납니다. 그러나 새 항목은 미완료여야 하고 앞뒤 공백을 제거해야 하므로 R1의 두 조건을 어깁니다. 성공처럼 보이는 JSON 객체가 출력되었다는 사실만으로 R1을 통과 처리할 수 없습니다. 어떤 필드가 어떤 기대값과 다르다는지 비교하여 실패 이유를 남깁니다.
완료 기준은 작업을 멈출 수 있는 판단 조건입니다. “코드가 실행됩니다” 대신 “명세의 사례에서 반환 결과와 전체 상태를 비교하고 일치 여부를 기록합니다”로 씁니다. 지금은 구현 전 문서 작업이므로 명세와 사례의 일관성이 이 모듈의 완료 조건입니다. 아직 작성하지 않은 앱의 기능 테스트를 통과했다고 적지 않습니다. 모듈 산출물의 완료와 트랙 프로젝트 전체의 완료를 분리합니다.
요구사항과 증거를 연결합니다
증거 표의 열은 요구사항, 확인 입력 또는 파일, 기대 결과, 실제 확인, 판정, 다음 행동으로 구성합니다. R1의 공백 제거 조건에는 “ 복습 ” 입력과 정리된 “복습” 기대값을 둡니다. 실제 결과가 공백을 포함하면 실패로 적고 정규화 구현을 다음 행동으로 지정합니다. 비교하지 않은 결과를 예상으로 채워 넣지 않습니다. 실제 확인 열은 직접 본 값이나 실행한 기록만 담습니다.
판정은 통과, 실패, 미확인으로 나눕니다. 통과는 지정한 확인에서 기대값과 일치했을 때 사용합니다. 실패는 실행한 비교에서 불일치가 있었을 때 사용합니다. 미확인은 아직 실행하거나 검토하지 않은 경우입니다. 조회를 호출하지 않았으면 조회가 실패했다고도 통과했다고도 적을 수 없습니다. 환경 문제로 실행하지 못한 검사는 미확인과 그 이유를 남겨 다음 작업자가 무엇부터 해야 하는지 알게 합니다.
증거의 범위도 함께 적습니다. 제목 판정 함수의 11개 테스트가 통과했다면 제목 규칙에 대한 증거입니다. 목록 상태를 다루지 않았으므로 번호 증가와 실패 시 상태 보존의 증거로 확대하지 않습니다. 한 개의 정상 생성 사례가 맞았어도 모든 생성 입력을 확인했다고 말하지 않습니다. 검증한 입력과 조건을 남기면 테스트가 어디까지 결과를 뒷받침하는지 판단할 수 있습니다.
검사기 자체의 한계를 이해해야 합니다. 미션의 bash check.sh는 spec.md의 필수 절과 TODO, cases.json의 고유 ID, 고정 수용 사례의 값, 성공·실패 개수 등을 확인합니다. 이 검사는 앱 함수를 호출하지 않습니다. 문서에 사용자 이야기가 실제로 충분한지나 추가 사례의 모든 기대값이 옳은지도 전부 판단하지 못합니다. 자동 검사가 확인한 부분과 사람이 읽어야 할 부분을 나란히 둡니다.
checker가 통과하려고 검사 파일을 바꾸거나 기대 결과를 가짜 앱의 출력으로 바꾸면 비교 기준을 잃습니다. 명세와 고정 사례의 입력은 합의한 기준으로 유지합니다. 구현 결과가 다르면 구현을 고칠 후보를 찾습니다. 요구 자체가 잘못되었다고 판단하면 먼저 변경 이유와 영향을 기록한 뒤 문서와 사례를 함께 수정합니다. 이번 미션에서는 제공된 계약을 유지하고 잘못된 기대 결과를 바로잡습니다.
다음 세션이 재현할 수 있게 남깁니다
검증 기록에는 실행한 명령, 실행 위치, 대상 파일, 결과 요약, 해석을 적습니다. “bash check.sh, 미션 압축을 푼 폴더, 문서 검사 실패 0개”만 적는 것보다 “앱 구현 검증은 미확인”을 함께 남기면 상태를 더 정확히 전달할 수 있습니다. 현재 파일을 저장한 뒤 검사를 다시 실행합니다. 저장하지 않은 편집 내용과 이미 실행한 파일이 다르면 그 결과는 현재 제출물의 증거가 아닙니다.
미션 starter에는 실제로 수정할 부분이 있습니다. 사용자와 목적에 남은 TODO를 자신의 사용자 이야기로 바꾸고 공백 제목, 41자 제목, 없는 번호 사례의 기대값을 계약대로 고칩니다. C01부터 C08까지는 고정 수용 사례입니다. 초기 상태와 입력을 변경하지 않고 expected와 expectedState를 검토합니다. C09 이후 제공 사례도 사람이 확인하며 원한다면 고유한 번호로 새 사례를 추가합니다.
검사기의 FAIL 줄은 고칠 파일과 차이를 좁히는 안내입니다. “C05 expected 불일치”는 41자 제목의 기대 결과를 계약과 비교하라는 뜻입니다. “C07 expectedState 불일치”는 없는 번호가 기존 항목을 지워도 되는지 확인하라는 뜻입니다. 여러 실패가 나오면 파일 읽기나 JSON 문법 문제부터 해결하고 다시 실행합니다. 형식이 정상일 때 입력과 기대값의 의미를 고치는 순서를 따릅니다.
명세에서 요구사항별 확인 방법을 정하면 구현 요청도 작아집니다. “R1 제목 판정부터 구현하고 C03~C06을 비교합니다”처럼 첫 조각을 정할 수 있습니다. AI가 전체 앱을 바꾼 결과를 받는 것보다 어떤 근거로 다음 변경을 진행하는지 설명하기 쉽습니다. 다만 이번 모듈은 문서와 사례를 제출하는 단계이므로 임의로 서버나 데이터베이스를 추가하지 않습니다. 다음 모듈은 이 문서에서 순수 함수 참조 모델을 시작합니다.
사람 검토는 모호한 문장과 자동 검사의 빈틈을 확인합니다. 사용자 목적이 구현 범위와 맞는지, 재시작 시 초기화가 드러나는지, 입력·출력·상태가 서로 충돌하지 않는지 읽습니다. 추가 사례가 정확한지는 명세로 다시 계산합니다. 기본 검사가 통과해도 rubric에 적힌 본인 판단과 AI 도움의 구분을 설명하지 못하면 제출물을 보완합니다. 숫자만 맞추는 대신 다음 사람이 사용할 자료를 만드는 것이 목적입니다.
검증을 끝낼 때에는 무한히 검사를 추가하지 않고 이번 완료 조건과 비교합니다. 문서 검사 통과, 고정 사례와 추가 사례의 사람 검토, 제외 범위와 미확인 항목 기록이 끝났으면 이 단계의 산출물을 넘깁니다. 앱 구현, HTTP 상태 매핑, API 동작은 후속 항목으로 남깁니다. 다음 행동이 구체적이면 미확인이라는 기록이 무책임한 공백이 아니라 재개 지점이 됩니다.
최종 evidence.md에는 문서 검사 결과와 직접 검토한 범위, 실패했다면 수정한 근거, 아직 실행하지 않은 앱 검증을 따로 씁니다. AI를 사용했다면 초안 작성이나 모호성 검토에 사용한 범위를 기록합니다. AI가 만든 문장을 본인이 확인하지 않았다면 확인한 것처럼 쓰지 않습니다. 신입에게 필요한 완료 판단은 결과를 크게 포장하는 능력보다 근거와 한계를 정확히 말하는 능력입니다.
이번 레슨을 마치면 정상 종료한 가짜 앱을 보고도 R1 실패와 R2·R3 미확인을 구분할 수 있어야 합니다. 더 읽기의 테스트 설계 원리는 이후 모듈에서 코드 검사로 확장합니다. 여기서는 명세의 기준을 지키고 현재 단계에서 확인한 증거를 남기는 데 집중합니다. 이렇게 정리한 spec.md, cases.json, evidence.md가 다음 모듈의 출발 자료가 됩니다.
따라하기
정상 종료하는 가짜 생성 함수를 실행합니다
다음 코드는 예외 없이 끝나지만 계약을 어깁니다. 제목의 공백과 done 값을 실제 출력에서 찾아 기록합니다.
import json
def fake_add(title):
return {"ok": True, "task": {"id": 1, "title": title, "done": True}}
print(json.dumps(fake_add(" 복습 "), ensure_ascii=False))실행 결과
{"ok": true, "task": {"id": 1, "title": " 복습 ", "done": true}}
요구사항별 증거 표를 작성합니다
R1 공백 제거: 실패, R1 새 항목 미완료: 실패, R2 조회: 미확인, R3 완료: 미확인으로 표를 작성합니다. 실제 값은 앞 단계 출력에서 가져오며 호출하지 않은 동작을 실패로 단정하지 않습니다.
미션 문서와 사례를 고칩니다
미션 starter.zip을 내려받아 풉니다. spec.md 사용자 목적의 TODO, cases.json C03·C05·C07의 기대 결과와 상태를 검토합니다. check.sh와 check_spec.py는 유지합니다. 폴더에서 bash check.sh를 실행하고 FAIL 줄의 사례 ID와 필드를 읽습니다. 이 명령의 실제 출력은 내려받은 수정 상태에 따라 달라집니다.
검증 범위와 인계를 기록합니다
evidence.md에 실행 명령, 문서 검사 결과, 사람의 검토 범위, 앱 구현 검증 미확인을 각각 적습니다. 다음 작업은 spec.md와 cases.json을 가져와 순수 함수 참조 모델을 작성하는 것입니다. 통과했어도 API 구현 완료라고 적지 않습니다.
확인 문제
실습
가짜 앱 출력으로 요구사항·입력·기대값·실제값·판정·다음 행동 표를 작성합니다. R1의 두 불일치와 호출하지 않은 R2·R3을 구분합니다. 모듈 미션의 spec.md와 cases.json을 보완한 뒤 bash check.sh를 실행하고 evidence.md에 문서 검사, 사람 검토, 앱 검증 미확인을 따로 기록합니다. 문서 검사를 앱 실행으로 확대하지 않는지 검토합니다.
더 읽기
면접 질문
- 명령의 정상 종료와 요구사항 충족은 어떻게 구분하나요?
- 검사하지 않은 기능을 인계할 때 어떤 판정과 다음 행동을 기록하나요?