호라이즌앱스 로고
← 기술 노트

자동 분류 테스트는 다 통과했는데 실제 파일에서 틀리는 이유

임균영조회 —

제가 만든 테스트 15건은 전부 통과였습니다. 화면에 초록 줄이 열다섯 개 쌓였습니다.

그 판별기에 실제 파일 다섯 장을 넣었습니다. 네 장이 '사람 확인 필요'로 걸렸습니다.

실물 검증에서 생긴 일입니다. 그대로 배포했다면 헛되이 사람을 부를 뻔했습니다.

무엇을 만들고 있었나

보험대리점(GA) 지사의 정산 업무였습니다. 매달 본사에서 마감 엑셀이 몇 묶음 내려옵니다.

건별 지급 명세, 시책, 신계약, 보유계약, 수수료율표 같은 파일입니다.

요청은 한 줄이었습니다. 담당자 한 명이 엑셀을 올리면 정산과 예측이 되게 해 달라는 것입니다.

그래서 투입구를 두 단계로 나눴습니다. 1단계는 업로드, 파일 종류 판별, 개인정보 가림 미리보기입니다. 2단계는 적재, 원장 잇기, 감시입니다.

판별기는 파일을 열어 시트 구성을 봅니다. 종류마다 "이런 시트가 이런 이름으로 있다"는 지문을 정해 두고 대조합니다. 확신이 낮으면 적재를 멈추고 사람을 부릅니다.

15건 합성 테스트가 본 것

테스트 케이스 15개는 제가 직접 만든 파일이었습니다. 15건 모두 통과했습니다.

판별 결과에는 확신 등급이 붙습니다. 등급이 낮게 나오면 담당자에게 확인 요청이 갑니다. 사람을 부르는 기준이니 너무 예민해도, 너무 둔해도 곤란합니다.

문제는 그 15개가 전부 제 머릿속에서 나왔다는 점입니다. 제가 상상한 종류의 파일만 시험한 셈입니다.

직접 만든 케이스 15건은 모두 통과했지만, 실제 파일 다섯 장 중 네 장은 지문과 다르다는 이유로 사람 확인에 걸렸습니다.

네 장이 걸린 이유

걸린 네 장은 시트 구성이 같았습니다. 'Data'라는 시트 하나만 든 종류였습니다.

이 종류는 지문표에 아예 없었습니다. 그런데 판별 규칙은 지문표에 없는 파일을 "지문과 다르다"로 읽고 점수를 깎았습니다.

모르는 종류와 틀린 파일을 같은 칸에 넣은 겁니다. 합성 케이스에는 시트 하나짜리 파일이 없었으니 이 규칙은 한 번도 시험대에 오르지 않았습니다.

그날 남긴 메모는 시험 데이터를 실물 이름과 실물 구조에서 떠 와야 한다는 것이었습니다.

비슷한 일은 같은 프로젝트의 수입 예측에서도 있었습니다. 수수료율표에서 같은 상품의 변형 행을 합쳐 버리는 오류를 합성 케이스는 못 잡았습니다.

과거 한 달의 실제 지급분에 거꾸로 대 보자 오염된 상품 라벨 367개가 드러났습니다.

조용히 반만 들어가는 결함

엑셀 파일(xlsx)은 속을 열면 압축 파일입니다. 이 압축을 읽는 부분에서 결함 3종이 나왔습니다. 리뷰와 실물 파일이 잡았습니다.

결함겉으로 보인 모습
정규식 검색 위치가 이어져 시트 절반을 건너뜀에러 없이 시트 일부만 적재
압축 해제 상한(512MB)이 서버 메모리 한도보다 큼상한에 닿기 전에 메모리 부족으로 죽음
압축 목록이 중간에 끊겨도 읽은 데까지 돌려줌파일 일부를 전체처럼 처리

맨 위 결함은 같은 검색 패턴을 되풀이해 쓰면서 생겼습니다. 앞선 검색이 멈춘 위치부터 다음 검색이 시작돼 시트 절반을 건너뛰었습니다.

압축 해제 상한은 방어선을 두고도 막지 못하는 구조였습니다. 상한에 닿기 전에 서버가 먼저 메모리 부족으로 멈추게 돼 있었습니다.

셋 다 '조용히 반만' 들어가는 종류입니다. 정산 데이터에서 저는 이 종류를 가장 무서워합니다.

에러가 나면 사람이 봅니다. 반만 들어가면 숫자가 그럴듯하게 틀린 채로 원장까지 흘러갑니다.

그래서 적재 뒤에는 데이터베이스 쪽에서 행 수를 다시 셉니다. 양식이 바뀌는 달의 적재 기준은 마감 엑셀 양식이 매달 바뀔 때에서 이어집니다.

시험장이 먼저 더러웠을 때

임시 데이터베이스에 실물 파일을 넣는 격리 시험을 돌렸습니다. 결과를 보니 행이 정확히 두 배였습니다.

원인은 이전에 실패한 실행이 남긴 잔재였습니다. 빈 줄 알았던 임시 DB에 앞선 시도의 행이 그대로 있었습니다.

초기화하고, 한 번만 호출하고, 행을 세는 단발 재현으로 갈랐습니다. 그 뒤로 격리 시험은 시작 전 카운트 0 확인을 첫 단계로 둡니다.

표본에서도 실수가 있었습니다. "값은 전부 지어낸 것"이라는 주석 아래에 제가 실제 회사 계좌번호를 넣었습니다. 바로 가짜 값으로 바꿨습니다.

그 뒤로 표본을 쓰기 전에 값이 어디서 왔는지 먼저 확인합니다.

통과가 아무것도 주장하지 않을 때

나중에 이 시스템을 감사하다가 더 곤란한 경우도 봤습니다. '자료 없음'을 0원으로 채우는 회귀를 일부러 심었는데 검사 167개가 전부 통과했습니다.

해당 검사는 "자료가 빈 달이 있으면"이라는 조건으로 시작했습니다. 실제 26개월 데이터에 빈 달이 하나도 없으니 그 줄은 늘 참이었습니다.

통과 표시는 같아도 그 검사는 아무것도 확인하지 않고 있었습니다. 결과표를 볼 때는 각 검사가 실제로 무엇을 주장하는지 확인하세요.

단위, 격리, 라이브 순서로

실물을 넣어야 보이는 비용도 있었습니다. 개인정보를 가리는 트리거는 행마다 열마다 정규식을 돌립니다. 건별 로우데이터 6.3만 행에서 이 과정이 222초 걸렸습니다.

손으로 만든 표본 몇십 행으로는 나오지 않는 숫자입니다.

쓰는 곳이 없는 두 시트는 헤더만 기록하고 행 적재를 보류했습니다. 보류 사유도 데이터에 남겼고, 시간은 12.6초로 줄었습니다.

최종 검증은 단계를 나눠 했습니다.

단계내용
단위 시험235건
격리 종단 시험임시 DB에 실물 파일 3개를 넣은 종단 시험
라이브 커밋1건, 장부를 바꾸지 않는 조건

원장은 빈 달만 새로 채우고 이미 있는 달은 차이를 보고만 하도록 쓰기 정책을 좁혀 두었습니다.

첫 라이브 커밋에서 바로 실전 발견이 나왔습니다. 옛 판을 넣어 보니, 나중 판이 지난달 숫자 3칸을 소급 정정해 둔 사실이 대조표에 떴습니다. 원장은 한 칸도 움직이지 않았습니다.

납품 테스트 결과표를 받은 날

외주로 자동 분류나 업로드 자동화를 맡기고 결과표를 받았다면 아래를 물어보세요. 제가 직접 겪은 장면에서 나온 질문입니다.

물어볼 것왜 묻는가
시험 파일은 어디서 왔나요직접 만든 15건은 실물 4장을 못 잡았습니다
실물 파일 몇 장으로 돌렸나요지문표에 없는 종류는 실물에서만 나옵니다
반만 들어간 경우를 잡나요시트 절반 유실은 에러 없이 지나갑니다
시험 전 빈 상태를 확인했나요행 2배의 원인은 이전 실행의 잔재였습니다
각 검사는 무엇을 주장하나요167개 통과가 공회전일 수 있습니다

매달 본사나 거래처 엑셀을 받아 손으로 맞추고 있다면 이런 투입구를 만들 수 있습니다. 파일을 올리면 종류를 판별하고, 가릴 정보를 미리 보여 주고, 다시 센 뒤에 적재하는 구조입니다.

보험GA 정산 데이터를 화면으로 본 예시는 보험GA 수수료·리스크 대시보드 데모에 있습니다. 지금 받는 파일 종류와 월 처리 흐름을 업무 시스템 문의에 적어 주시면 어디까지 자동으로 넘길 수 있을지 먼저 판단해 드립니다.

통과 표시를 믿기 전 순서

자동화를 맡기기 전이나 납품을 받기 전에, 시험 데이터를 이 순서로 준비해 보세요.

  1. 실제 파일 사본을 받습니다. 지난 몇 달 치 마감 파일처럼 실제로 올라올 파일을 그대로 씁니다.
  2. 개인정보만 가립니다. 이름, 주민번호, 계좌 같은 값만 바꾸고 나머지는 둡니다.
  3. 파일 이름과 시트 구성은 그대로 둡니다. 시트가 하나뿐인 파일, 이름 꼬리가 바뀐 파일이 바로 시험거리입니다.
  4. '조용히 반만 들어감'을 잡는 항목을 넣습니다. 파일의 행 수와 적재된 행 수를 대조하는 검사가 최소 하나 있어야 합니다.
  5. 시험 시작 전에 빈 상태를 확인합니다. 임시 DB의 행 수가 0인지 먼저 보고 돌립니다.
  6. 표본 값의 출처를 확인합니다. 지어낸 값이라고 적힌 칸에 실제 값이 섞여 있지 않은지 봅니다.

이어서 읽기