실제 CPython 실행 검수 보고서
검수일: 2026-10-11
환경: CPython 3.12.14
외부 패키지: 사용 안 함
모든 자료: 합성 예제
표시 경로는 임시 실습 폴더를 . 로 치환함.

[전체 테스트]
python -m unittest discover -s tests -v
exit_code=0

test_cli_reports_success_and_failure_without_traceback (test_replace_ids.ReplacementTests.test_cli_reports_success_and_failure_without_traceback) ... ok
test_duplicate_original_mapping_key_rejected (test_replace_ids.ReplacementTests.test_duplicate_original_mapping_key_rejected) ... ok
test_duplicate_surrogate_mapping_id_rejected (test_replace_ids.ReplacementTests.test_duplicate_surrogate_mapping_id_rejected) ... ok
test_empty_input_and_duplicate_or_empty_row_id_rejected (test_replace_ids.ReplacementTests.test_empty_input_and_duplicate_or_empty_row_id_rejected) ... ok
test_empty_or_whitespace_input_key_rejected (test_replace_ids.ReplacementTests.test_empty_or_whitespace_input_key_rejected) ... ok
test_exact_five_rows_three_stable_ids_and_projection (test_replace_ids.ReplacementTests.test_exact_five_rows_three_stable_ids_and_projection) ... ok
test_existing_file_or_broken_symlink_not_overwritten (test_replace_ids.ReplacementTests.test_existing_file_or_broken_symlink_not_overwritten) ... ok
test_existing_output_directory_not_overwritten (test_replace_ids.ReplacementTests.test_existing_output_directory_not_overwritten) ... ok
test_failed_validation_can_be_fixed_and_run_again (test_replace_ids.ReplacementTests.test_failed_validation_can_be_fixed_and_run_again) ... ok
test_fresh_run_reuses_mapping_with_identical_bytes (test_replace_ids.ReplacementTests.test_fresh_run_reuses_mapping_with_identical_bytes) ... ok
test_invalid_or_empty_mapping_rejected (test_replace_ids.ReplacementTests.test_invalid_or_empty_mapping_rejected) ... ok
test_invalid_schema_or_row_width_rejected (test_replace_ids.ReplacementTests.test_invalid_schema_or_row_width_rejected) ... ok
test_mapping_folder_cannot_overlap_public_output (test_replace_ids.ReplacementTests.test_mapping_folder_cannot_overlap_public_output) ... ok
test_missing_input_or_mapping_creates_no_output (test_replace_ids.ReplacementTests.test_missing_input_or_mapping_creates_no_output) ... ok
test_reordered_input_reuses_same_key_ids (test_replace_ids.ReplacementTests.test_reordered_input_reuses_same_key_ids) ... ok
test_unknown_key_rejected_without_extending_mapping (test_replace_ids.ReplacementTests.test_unknown_key_rejected_without_extending_mapping) ... ok
test_write_failure_cleans_only_new_output_then_retry_succeeds (test_replace_ids.ReplacementTests.test_write_failure_cleans_only_new_output_then_retry_succeeds) ... ok

----------------------------------------------------------------------
Ran 17 tests in 0.062s

OK

[실제 CLI 검수]
normal
python replace_ids.py --input synthetic_input/roster.csv --mapping private_mapping/id_mapping.csv --output public/run_01
exit_code=0
완료: 5행 → ./public/run_01/analysis.csv


reuse
python replace_ids.py --input synthetic_input/roster.csv --mapping private_mapping/id_mapping.csv --output public/run_02
exit_code=0
완료: 5행 → ./public/run_02/analysis.csv


reordered
python replace_ids.py --input synthetic_input/roster_reordered.csv --mapping private_mapping/id_mapping.csv --output public/reordered
exit_code=0
완료: 5행 → ./public/reordered/analysis.csv


empty key
python replace_ids.py --input negative_cases/empty_key.csv --mapping private_mapping/id_mapping.csv --output public/rejected_empty
exit_code=2

실패: 입력 2행: 빈 값 또는 양끝 공백 포함 original_key입니다.

unknown key
python replace_ids.py --input negative_cases/unknown_key.csv --mapping private_mapping/id_mapping.csv --output public/rejected_unknown
exit_code=2

실패: 입력 2행: 대응표에 미등록 original_key입니다.

duplicate original
python replace_ids.py --input synthetic_input/roster.csv --mapping negative_cases/duplicate_original_mapping.csv --output public/rejected_duplicate_key
exit_code=2

실패: 대응표 5행: 중복 original_key입니다.

duplicate surrogate
python replace_ids.py --input synthetic_input/roster.csv --mapping negative_cases/duplicate_surrogate_mapping.csv --output public/rejected_duplicate_id
exit_code=2

실패: 대응표 5행: 중복 surrogate_id입니다.

output conflict
python replace_ids.py --input synthetic_input/roster.csv --mapping private_mapping/id_mapping.csv --output public/run_01
exit_code=2

실패: 출력 경로가 이미 있습니다. 새로운 폴더 이름을 사용하세요.

public/run_01/analysis.csv: 5행 / UTF-8 BOM / ID=S001,S002,S001,S003,S002 / 원키·이름 열 없음
public/reordered/analysis.csv: 5행 / UTF-8 BOM / ID=S002,S003,S001,S002,S001 / 원키·이름 열 없음

[원본 및 대응표 보존: 바이트 + SHA-256]
synthetic_input/roster.csv: before=f73633220a31584607ad58e9f1d1e5b9d4dd61ba639e16121b86ab2cc6ec38c2; after=f73633220a31584607ad58e9f1d1e5b9d4dd61ba639e16121b86ab2cc6ec38c2; bytes_equal=True
private_mapping/id_mapping.csv: before=889eb644a2b4f979dfbf23b12d35fecb6ba983fd1fc75f9c3aec681961d02c75; after=889eb644a2b4f979dfbf23b12d35fecb6ba983fd1fc75f9c3aec681961d02c75; bytes_equal=True

[종합]
전체 unittest 17/17 통과. 정상 CLI 3회 종료코드 0, 기대 실패 CLI 5회 종료코드 2.
같은 입력·고정 대응표의 새 폴더 재실행은 결과 바이트 동일.
순서 변경 후에도 같은 원키에 같은 대체 ID 유지.
쓰기 오류 복구 테스트는 csv.DictWriter.writerows에 OSError를 주입하는 단위 테스트임.
원본 입력·대응표를 수정하지 않았고, 실패 시 기존 출력도 보존됨.
익명성·재식별 방지·법적 적합성·보안 보장은 검증 대상이 아님.
