수동 QA (품질 보증)수동 QA 엔지니어

잘못된 데이터 구조 처리, 혼합 문자 인코딩(**UTF-8** 대 **Windows-1252**), 메모리 효율적인 스트리밍을 통해 **100MB**를 초과하는 파일 처리와 부분 유효성 검사 실패 시 원자 트랜잭션 롤백 메커니즘을 검증하기 위한 체계적인 수동 테스트 방법론을 구성하시오.

Hintsage AI 어시스턴트로 면접 통과

질문에 대한 답변

CSV (Comma-Separated Values)는 2005년 RFC 4180에서 공식화되었음에도 불구하고 데이터 교환의 공용 언어로 남아 있으며, 그 뿌리는 1972년 IBM Fortran 구현으로 거슬러 올라갑니다. 초기 구현은 CSV를 단순한 텍스트 분할로 처리하여 인코딩의 복잡성, 구분 기호의 변형 및 현대 세계화에서 문제를 일으키는 줄 바꿈 모호성을 무시했습니다. 근본적인 도전 과제는 CSV가 자기 설명적 메타데이터를 결여하고 있다는 것입니다. 파서는 대량 삽입 중 ACID 준수를 유지하면서 구분 기호, 인코딩 및 스키마를 추론해야 합니다. 잘못된 행, 보이지 않는 BOM (Byte Order Mark) 변화 및 메모리 제한은 기능적 검증과 성능, 보안 및 데이터 무결성 문제 간의 교차점에서 테스트 표면을 만듭니다.

체계적인 방법론은 이러한 위험을 전체적으로 해결하기 위해 네 가지 구별된 검증 단계를 요구합니다. 첫째, 헤더 손상을 감지하기 위해 BOM 서명이 있는 경우와 없는 경우의 문자 인코딩(UTF-8, UTF-16, Windows-1252, ISO-8859-1)에 대한 동등 분할 검증을 수행합니다. 둘째, 파일 크기(0바이트, 1MB, 100MB, 1GB+)에 대한 경계값 분석을 통해 Node.js 또는 JVM 제약 조건 하에서 스트리밍 동작과 메모리 안정성을 검증합니다. 셋째, 닫히지 않은 따옴표, 혼합된 줄 끝(CRLFLF), 수식 주입 시도 및 SQL 이스케이프 시퀀스를 포함한 잘못된 구조에 대한 부정적 테스트를 실시합니다. 넷째, 데이터베이스 저장 지점이나 스테이징 테이블을 사용한 트랜잭션 무결성 검증을 통해 부분 실패가 깨끗하게 롤백되도록 하여 부작용이나 고아 레코드가 생성되지 않도록 합니다.

개인적인 상황

핀테크 스타트업에서 클라우드 마이그레이션 중 레거시 Oracle 데이터베이스에서 현대 PostgreSQL 플랫폼으로 고객 포트폴리오를 가져와야 했습니다. 레거시 시스템은 Windows-1252 인코딩을 사용하여 중괄호 스마트 따옴표와 세미콜론 구분 기호로 CSV 내보내기를 생성했으며, 저희 Node.js 애플리케이션은 쉼표 구분기호를 사용하는 UTF-8을 예상했기에 즉각적인 호환성 문제가 발생했습니다.

초기 수동 테스트에서는 Docker 스테이징 환경에서 쉽게 통과한 10KB의 작은 파일을 사용했습니다. 그러나 80MB를 초과하는 프로덕션 파일은 OOM (Out of Memory) 오류로 인해 Heroku 다이노를 크래시시켰습니다. 파서가 전체 파일을 RAM에 로드하여 DOM 스타일 파싱을 하였기 때문입니다. 또한, 120,000번째 행에 잘못된 날짜 형식(02/30/2023)이 포함되어 있을 때 시스템이 예외를 발생시켰지만, 이미 이전의 119,999 행이 데이터베이스에 커밋되었습니다. 이로 인해 데이터베이스는 불일치 상태가 되었고 수동 SQL 정리가 필요하였으며, 인코딩 문제는 é와 같은 국제 고객 이름이 잘못 변환되어 데이터 품질이 손상되었습니다.

고려된 솔루션 1: 서버 메모리를 2GB에서 16GB로 늘리고 전체 가져오기를 단일 단일 데이터베이스 트랜잭션으로 감싸는 수직적 확장. 장점으로는 최소한의 코드 변경과 즉각적으로 작동하는 간단한 구현이 있습니다. 단점으로는 클라우드 네이티브 12-factor 원칙을 위반하는 비싼 인프라와 인코딩 손상을 해결하지 못하며, 향후 파일이 500MB에 도달할 경우 OOM 크래시가 지연되고, 가져오기 중 라이브 사용자에게 영향을 미치는 데이터베이스 테이블 잠금이 연장됩니다.

고려된 솔루션 2: Python 스크립트를 사용하여 인코딩을 변환하고 iconv를 사용하여 클라이언트 측에서 전처리하고 1000행 덩이로 큰 파일을 분할하여 업로드하는 방법. 장점으로는 주요 애플리케이션 코드베이스를 변경하지 않고도 즉각적인 메모리 및 인코딩 문제를 해결할 수 있습니다. 단점으로는 수동 개입이 필요한 부서지는 외부 의존성, 자동화된 워크플로가 중단됨, 덩이 경계를 넘어서는 크로스 행 검증을 위한 참조 무결성 파괴 및 WindowsmacOS 개발 환경에서의 유지 관리가 어려움이 있습니다.

고려된 솔루션 3: Papa Parseiconv-lite와 같은 스트리밍 파서를 사용하여 인코딩 감지를 구현하고, 1000행마다 데이터베이스 저장 지점을 구현하고, 검증을 위한 스테이징 테이블을 활용하는 리팩토링. 장점으로는 파일 크기와 관계없이 약 150MB의 일정한 메모리를 유지하고, 자동 인코딩 정규화를 통해 UTF-8로 변환하며, 유효한 배치를 보존하면서 특정 오류 행을 고립시키는 세분화 롤백 기능이 있습니다. 단점으로는 상당한 아키텍처 리팩토링이 필요하고, 데이터베이스 행 ID를 원래의 CSV 행 번호에 되돌리기 위한 복잡한 오류 보고 로직이 필요하며, 트랜잭션 경계 조건에 대한 테스트 복잡성이 증가합니다.

선택된 솔루션: 우리는 근본 원인을 해결하는 솔루션 3을 선택했습니다. 이는 장기적인 성장을 위한 지속 가능한 아키텍처를 제공했습니다. 개발 팀은 64KB 덩이로 파일을 처리하는 SAX 스타일 스트리밍을 구현하여, 파싱 이전에 모든 입력을 UTF-8로 변환하고, 1000행마다 서브 트랜잭션을 커밋하며 롤백 기능을 유지하는 PostgreSQL 저장 지점을 활용했습니다.

결과: 시스템은 150MB를 초과하는 메모리 스파이크 없이 총 4GB에 달하는 50개의 프로덕션 파일을 성공적으로 가져왔습니다. 인코딩 변환은 Windows-1252 스마트 따옴표와 유로 기호를 올바르게 처리했습니다. 잘못된 날짜가 포함된 3개의 파일이 있을 때 시스템은 데이터의 98%를 성공적으로 가져오며, 수정을 필요로 하는 정확한 행을 식별하는 정밀한 오류 보고서를 생성했습니다. 이로 인해 마이그레이션 시간은 예상 3주에서 4일로 단축되었고 데이터베이스 손상 사건은 없었습니다.

후보자들이 자주 놓치는 점

귀하의 CSV 파서가 열 헤더를 손상시키지 않고 BOM (Byte Order Mark) 서명을 올바르게 처리하도록 어떻게 검증합니까?

많은 테스터는 ExcelNotepadUTF-8 파일에 보이지 않는 BOM 바이트(0xEF 0xBB 0xBF)를 앞뒤로 추가함으로써 첫 번째 열 헤더가 \ufeffCustomerID로 파싱되고, CustomerID가 아닌 경우를 간과합니다. 파서가 이러한 바이트를 문자 그대로 처리할 경우 표 필드 매핑 실패가 발생하며 이는 표준 디버그 로그나 IDE 콘솔에서 보이지 않습니다. 이를 테스트하기 위해 hex editors 또는 printf '\xEF\xBB\xBF' > file.csv와 같은 셸 명령어를 사용하여 BOM 유무에 따라 파일을 생성한 후, 애플리케이션이 이러한 바이트를 섭취 중에 제거하거나 Unicode NFC 형식을 사용하여 문자열을 정규화하는지 확인합니다. BOM이 있는 경우 바이트 길이 계산이 문자 길이 계산과 다르게 되는지 확인하여 보이지 않는 문자로 인해 열 이름 길이에 대한 데이터베이스 제약이 위반되지 않도록 합니다.

UI 레이어에서 CSV 구분 기호를 테스트하는 것과 API 레이어에서 테스트하는 것의 차이점은 무엇이며, 왜 이것이 데이터 무결성에 중요합니까?

후보자들은 종종 행복 경로(구분 기호로 쉼표만 사용하는 경우)만 테스트하며, 유럽 로케일이 지역 Excel 설정으로 인해 세미콜론을 사용하므로 UI 검증과 API 파싱 간의 불일치가 발생하는 점을 무시합니다. API 엔드포인트는 탭으로 구분된 파일을 허용할 수 있지만 UI는 쉼표를 강제할 수 있으며, 이는 생산 데이터가 테스트 데이터와 다를 때 파싱 오류나 데이터 단편화를 초래할 수 있습니다. 테스트 방법론은 Content-Type 헤더가 실제 구분 기호와 일치하는지 확인하고, 탭, 파이프(|), 세미콜론과 함께 테스트 케이스를 생성하여 파서가 자동 감지하거나 엄격히 검증하는지 확인해야 합니다. 구분 기호가 포함된 인용된 필드(예: "Smith, Jr., John")가 별도의 열로 분할되지 않도록 하여, 하류 CRM 통합에서 문제가 생기지 않도록 합니다.

가져온 데이터가 나중에 스프레드시트에서 내보내거나 볼 때 CSV 주입 공격에 대한 보안 테스트 케이스를 어떻게 설계합니까?

수동 테스터들은 종종 악의적 페이로드(예: =cmd|'/C calc'!A0 또는 +HYPERLINK("http://evil.com","Click"))가 관리자에게 다운로드 되어 Excel 또는 LibreOffice에서 가져온 데이터를 열 때 실행되는 CSV 수식 주입을 놓칩니다. 이는 저장된 XSS를 통한 CSV로, 관리자 워크스테이션을 손상시키거나 데이터를 유출할 수 있습니다. 테스트 방법론은 수식 트리거(=, +, -, @)가 붙은 입력 필드를 생성한 후 시스템 명령이나 JavaScript 페이로드를 추가한 후, 서버 측에서 수식이 중립화되도록 아포스트로프(')를 선행하여 추가하거나 위험한 문자를 완전히 제거하는지 검증합니다. 가져오기에서 저장, 내보내기까지 전체 사이클을 테스트하여 다운로드한 CSV 파일이 스프레드시트 애플리케이션에서 열 때 수식이 실행되는 것이 아니라 문자 그대로 텍스트로 렌더링되는지 확인합니다.