릴리스 직전, 앱이 입장권을 QR 코드 PNG로 저장했고 화면의 미리보기도 정상일 수 있습니다. 하지만 실제 스캔은 크기 조정 과정의 보간, 가장자리 잘림, 전경과 배경의 낮은 대비 때문에 실패할 수 있습니다. 단순히 “파일이 존재한다”고 확인하는 대신, 클라우드 Mac에서 앱이 최종 출력한 이미지를 꺼내 Vision으로 다시 읽고 내용을 대조하는 편이 낫습니다. iOS 회귀 테스트에 넣기 좋은 파일 단위 검사입니다.
검증 범위 먼저 정하기
여기서 검사할 대상은 테스트 스크립트가 자체 생성한 QR 코드가 아니라 앱이 실제로 기록한 PNG입니다. 고정 테스트 페이로드는 case-123이며, 앱의 테스트 진입점은 해당 이미지를 샌드박스의 Documents/qr-sample.png에 저장해야 합니다. 제품이 QR 코드를 화면에만 그린다면 기존 내보내기 기능으로 파일을 확보하세요. 프로덕션 출력을 대신할 별도의 테스트용 생성기를 만들지는 마세요.
통과 조건은 세 가지입니다. 앱 컨테이너에서 파일을 꺼낼 수 있어야 하고, Vision이 QR 코드 하나만 인식해야 하며, 디코딩된 문자열이 예상 값과 정확히 일치해야 합니다. 파일 해시는 주요 검증 조건으로 적합하지 않습니다. 인코딩 설정이나 PNG 메타데이터가 바뀌면 QR 코드의 내용은 그대로여도 바이트가 달라질 수 있습니다.
여기서 “인식 가능”하다는 것은 내보낸 디지털 이미지에만 해당합니다. 카메라 초점, 화면 밝기, 인쇄 크기는 추가 변수가 되므로 파일 단위 검증이 실제 스캔 테스트를 대신할 수는 없습니다.
시뮬레이터에서 최종 파일 가져오기
먼저 실행 중인 iOS 시뮬레이터에서 테스트 진입점을 실행하고, 앱이 약속한 경로에 파일을 썼는지 확인합니다. 다음 명령은 환경 변수 BUNDLE_ID에 테스트 대상 앱의 실제 bundle identifier가 설정되어 있어야 합니다. get_app_container는 해당 앱의 데이터 컨테이너 경로를 반환합니다.
test -n "$BUNDLE_ID" || exit 2
APP_DATA=$(xcrun simctl get_app_container booted "$BUNDLE_ID" data) || exit 1
mkdir -p artifacts
cp "$APP_DATA/Documents/qr-sample.png" artifacts/qr-sample.png
file artifacts/qr-sample.png
cp가 실패하면 앱이 현재 실행 중인 시뮬레이터에서 동작했는지, 내보내기 로직이 실제로 Documents에 파일을 썼는지부터 확인하세요. 개발 머신에서 같은 이름의 이미지를 골라 대신 넣으면 회귀 검사가 앱을 거치지 않게 됩니다. 앱이 매번 여러 파일을 출력한다면 테스트 진입점에서 일정한 파일명을 사용하고, 실행할 때마다 오래된 파일을 정리해 이전 결과를 잘못 읽지 않도록 해야 합니다.
Vision으로 디코딩하고 페이로드 대조하기
다음 내용을 작업 디렉터리에 qr-check.swift로 저장합니다. 스크립트는 PNG 경로와 예상 텍스트를 인수로 받습니다. 입력, 인식 또는 대조에 실패하면 0이 아닌 상태 코드로 종료하므로 파이프라인에서 바로 판정할 수 있습니다.
import Foundation
import Vision
guard CommandLine.arguments.count == 3 else {
fputs("usage: swift qr-check.swift IMAGE EXPECTED\n", stderr)
exit(2)
}
let url = URL(fileURLWithPath: CommandLine.arguments[1])
let expected = CommandLine.arguments[2]
let request = VNDetectBarcodesRequest()
request.symbologies = [.qr]
do {
try VNImageRequestHandler(url: url, options: [:]).perform([request])
let codes = (request.results ?? []).filter { $0.symbology == .qr }
guard codes.count == 1,
codes[0].payloadStringValue == expected else {
fputs("QR count or payload mismatch\n", stderr)
exit(1)
}
print("QR payload verified")
} catch {
fputs("QR image could not be analyzed\n", stderr)
exit(1)
}
swift qr-check.swift artifacts/qr-sample.png case-123을 실행합니다. 인식된 코드의 개수만 확인해서는 안 됩니다. 인식에 성공한 코드에도 이전 주문 번호나 잘못된 접두사, 잘린 텍스트가 들어 있을 수 있습니다. 정식 테스트 데이터에 실제 자격 증명을 넣어서도 안 됩니다. 비즈니스 페이로드에 민감한 필드가 있다면, 형식과 파싱 로직을 검사할 수 있는 전용 무효 테스트 값을 사용하세요.
실패 원인을 단계별로 찾기
먼저 내보낸 파일을 확인하고, 그다음 인식 결과를 살펴본 뒤, 마지막으로 QR 코드 생성 코드를 점검하세요. 이렇게 하면 “애초에 내보내지지 않은 경우”와 “내보냈지만 읽을 수 없는 경우”를 구분할 수 있습니다.
| 증상 | 우선 확인할 항목 |
|---|---|
| PNG를 찾을 수 없음 | 시뮬레이터 선택, bundle identifier, 샌드박스 경로, 오래된 파일 정리 |
| Vision이 코드를 찾지 못함 | 이미지 잘림, 지나친 축소 또는 손실 처리 여부 |
| 코드가 여러 개 인식됨 | 내보낸 이미지에 다른 QR 코드가 섞였는지 여부 |
| 페이로드가 일치하지 않음 | 인코딩 전 텍스트, 문자 인코딩, 캐시, 내보내기 시점 |
앱이 Core Image로 QR 코드를 생성한다면, 생성기의 outputImage에서 전체 경계를 보존한 다음 정수 배율로 확대하고 마지막에 PNG로 저장하세요. 공유나 스크린샷 경로에서 보간을 거쳐 다시 축소하지 않는지도 확인해야 합니다. 미리보기가 매끄러워 보여도 사각형의 경계가 선명하게 유지됐다는 뜻은 아닙니다. 다크 모드를 사용한다면 최종 파일의 색상도 확인하세요. 화면 배경과 내보낸 이미지의 배경은 다를 수 있으며, 투명 영역은 다른 배경색 위에서 대비를 잃을 수 있습니다.
검사가 잘못된 결과를 내지 않도록 하기
테스트 이미지 하나, 명확한 페이로드 하나, 출력 경로 하나를 고정하되, 이미지는 매번 해당 실행에서 나온 결과를 가져오세요. 길이가 다른 페이로드, 비 ASCII 문자 또는 구분자가 포함된 페이로드를 검사하려면 테스트 케이스를 각각 만들고 하나씩 대조해야 합니다. 여러 예상 문자열 중 “하나만 포함하면 통과”하도록 만들지 마세요. QR 코드 디코딩에 성공했다고 비즈니스 링크까지 동작하는 것은 아닙니다. 이동 동작을 검증해야 한다면 별도의 테스트 계층에서 파싱과 라우팅을 확인하세요.
회귀 테스트 흐름에 연결하기
기존 시뮬레이터 테스트가 끝난 뒤 파일을 가져오는 명령과 Swift 스크립트를 실행하고, 어느 단계든 0이 아닌 종료 코드가 나오면 해당 작업을 실패로 처리하세요. 실패했을 때는 이번 실행의 PNG와 스크립트 오류 출력을 보관하면 내보내기 경로가 바뀌었는지, 이미지 처리로 품질이 저하됐는지 판단하기 쉽습니다. 통과한 뒤에는 검증 상태만 기록하면 되며, 비즈니스 데이터가 담긴 이미지를 장기간 보관할 필요는 없습니다.
마지막으로 네 가지를 확인합니다. 이미지가 앱의 최종 출력물인지, 이전 실행의 잔여 파일을 읽지 않았는지, Vision이 코드 하나만 읽었는지, 페이로드가 고정 테스트 값과 정확히 일치하는지입니다. 이 조건을 확인하면 파일 단위 QR 코드 회귀 검사의 범위가 명확해지고 반복 가능해집니다. 화면 표시나 인쇄물 전달까지 검증해야 한다면 실제 기기에서 스캔하는 테스트를 추가하세요.
자주 묻는 질문
Vision 검사만으로 실제 카메라 스캔 테스트를 대체할 수 있나요?
아니요. 파일의 해독 가능성과 데이터는 확인할 수 있지만 화면 밝기, 카메라 초점, 인쇄 크기는 실제 환경에서 별도로 확인해야 합니다.
테스트 코드가 QR 코드를 직접 생성하면 안 되나요?
직접 생성한 파일만 검사하면 앱의 실제 내보내기 과정에서 생기는 축소, 색상 변경, 잘림 문제를 놓칩니다. 앱이 저장한 최종 PNG를 입력으로 사용해야 합니다.
독립형 Mac mini로 다음 단계를 검증하세요
VMCommit은 M4 독립형 Mac mini를 일간, 주간, 월간 또는 분기 단위로 대여합니다. 모델과 위치를 선택한 뒤 콘솔에서 실시간 이용 가능 여부를 확인하세요.