simctl addmedia로 재현 가능한 iOS 사진 가져오기 테스트 만들기
사용자가 사진 보관함에서 이미지를 선택하면 앱은 방향 정보를 읽고, 썸네일을 생성하고, 원본 이미지를 압축한 뒤 업로드해야 할 수 있습니다. 동영상에는 재생 시간, 인코딩, 파일 크기에 따른 분기까지 추가됩니다. 개발용 Mac에서 한 번 직접 조작해 보는 것만으로는 다음 빌드에서도 동일한 입력 세트를 처리할 수 있다고 보장할 수 없습니다. 더 안정적인 방법은 미디어 파일을 테스트 픽스처로 저장소에 포함하고, 클라우드 Mac에서 전용 시뮬레이터를 초기화한 다음 simctl addmedia로 사진 보관함에 주입하는 것입니다.
먼저 검증할 경계 정의하기
이 테스트는 시스템 사진 앱을 자동으로 조작하는 것이 아니라 앱과 시스템 사진 보관함 사이의 인터페이스에 초점을 맞춰야 합니다. 최소한 다음 네 가지 경로를 다루는 것이 좋습니다.
- 앱이 예상한 수의 이미지와 동영상을 찾을 수 있다.
- 선택기가 결과를 반환한 뒤 파일 유형, 픽셀 크기, 동영상 재생 시간이 예상과 일치한다.
- 압축 또는 업로드 작업이 우연히 얻은 미리보기가 아니라 원본 리소스를 사용한다.
- 지원하지 않는 형식, 지나치게 큰 파일, 권한 변경이 명확한 오류 분기로 이어진다.
simctl addmedia는 시뮬레이터에서 읽기 및 처리 흐름을 검증하는 데 적합하지만, 카메라 촬영, 기기 전용 인코딩, 실제 저장 공간 압박 테스트를 대신할 수는 없습니다. 이러한 경계를 테스트 설명에 명시해 두면 실패가 발생했을 때 시뮬레이터의 제약을 제품 결함으로 잘못 판단하는 일을 피할 수 있습니다.
회귀 테스트의 목표는 가능한 한 많은 미디어를 넣는 것이 아니라, 각 미디어가 이름을 붙일 수 있고 반복 및 진단이 가능한 동작 하나에 대응하도록 만드는 것입니다.
작고 안정적인 미디어 픽스처 준비하기
저장소에 Tests/Fixtures/Media를 만들고 테스트에 필요한 최소한의 파일만 커밋합니다. 파일명은 예상 용도를 드러내야 하며 카메라가 자동으로 생성한 이름은 사용하지 않는 것이 좋습니다.
| 파일 | 용도 | 주요 어설션 |
|---|---|---|
portrait.jpg |
방향 정보가 포함된 세로 이미지 | 방향 보정 후 너비와 높이가 올바름 |
transparent.png |
투명 채널이 포함된 이미지 | 내보낸 뒤에도 투명도가 유지됨 |
short.mov |
짧은 동영상 | 재생 시간과 미디어 유형이 올바름 |
invalid.txt |
미디어가 아닌 파일 | 주입 단계에서 명시적으로 거부됨 |
이미지 도구가 픽스처를 의도치 않게 다시 쓰지 못하도록 SHA-256 목록도 함께 저장합니다.
cd Tests/Fixtures/Media
shasum -a 256 portrait.jpg transparent.png short.mov > SHA256SUMS
shasum -a 256 -c SHA256SUMS
작업 실행 중에 픽스처를 다시 인코딩하지 마십시오. 시스템 버전에 따라 인코더가 서로 다른 메타데이터를 기록할 수 있어 문제가 “앱 동작의 변화”가 아니라 “입력이 이미 달라진 상태”로 바뀔 수 있습니다. 동적 파일이 꼭 필요하다면 생성 스크립트, 매개변수, 생성된 파일의 다이제스트를 모두 기록해야 합니다.
작업마다 시뮬레이터 격리하기
장기간 실행되는 시뮬레이터를 공유하면 사진 보관함 자산, 권한 기록, 백그라운드 프로세스가 남습니다. 가장 단순한 기준선은 스케줄링 계층에서 DEVICE_UDID를 전달하고, 작업이 시작되면 시뮬레이터를 종료하고 초기화한 뒤 부팅이 완료될 때까지 기다리는 것입니다.
set -euo pipefail
: "${DEVICE_UDID:?DEVICE_UDID is required}"
: "${BUNDLE_ID:?BUNDLE_ID is required}"
xcrun simctl shutdown "$DEVICE_UDID" 2>/dev/null || true
xcrun simctl erase "$DEVICE_UDID"
xcrun simctl boot "$DEVICE_UDID"
xcrun simctl bootstatus "$DEVICE_UDID" -b
xcrun simctl privacy "$DEVICE_UDID" reset photos "$BUNDLE_ID" || true
xcrun simctl privacy "$DEVICE_UDID" grant photos "$BUNDLE_ID"
시뮬레이터 모델과 시스템 버전도 작업 설정에서 고정해야 합니다. name=iPhone만 지정하고 Xcode가 임의로 선택하게 두어서는 안 됩니다. 병렬 작업은 서로 다른 UDID를 사용해야 합니다. 그렇지 않으면 한 작업이 erase를 실행하는 동안 다른 작업이 테스트를 진행하고 있을 수 있습니다.
권한 테스트는 두 그룹으로 나누는 것이 좋습니다. 기본 흐름에서는 사진 보관함 권한을 미리 부여해 미디어 처리를 검증하고, 권한 거부 흐름에서는 revoke를 별도로 실행해 앱의 안내와 복구 진입점만 어설션합니다. 시스템 팝업의 표시 여부가 테스트 성공이나 실패를 결정하게 만들지 마십시오.
미디어 주입 후 대상 테스트 실행하기
주입 전에 확장자와 다이제스트를 확인한 다음, 지원되는 파일을 한 번에 addmedia로 전달합니다.
FIXTURES="$PWD/Tests/Fixtures/Media"
shasum -a 256 -c "$FIXTURES/SHA256SUMS"
xcrun simctl addmedia "$DEVICE_UDID" \
"$FIXTURES/portrait.jpg" \
"$FIXTURES/transparent.png" \
"$FIXTURES/short.mov"
xcodebuild test \
-workspace Demo.xcworkspace \
-scheme Demo \
-destination "platform=iOS Simulator,id=$DEVICE_UDID" \
-only-testing:MediaImportTests \
-resultBundlePath "$PWD/Artifacts/MediaImport.xcresult"
addmedia가 성공을 반환했다는 것은 명령이 파일을 받아들였다는 뜻일 뿐, 앱이 올바른 자산을 이미 확인했다는 의미는 아닙니다. 테스트 코드는 사진 보관함 조회 결과가 예상 수에 도달할 때까지 기다리되 제한된 타임아웃을 설정해야 합니다. 어설션은 미디어 유형, 픽셀 크기, 재생 시간 범위, 비즈니스 로직의 생성 결과를 우선 사용해야 합니다. 가져온 시간과 리소스 생성 시간이 다를 수 있으므로 시스템 사진 보관함의 표시 순서에 의존해서는 안 됩니다.
앱이 파일을 업로드한다면 네트워크 계층을 로컬 테스트 구현으로 교체하고 수신한 MIME 유형, 바이트 수, 다이제스트를 기록할 수 있습니다. 이렇게 하면 원본 리소스를 읽었는지 확인하면서 외부 네트워크 변동이 회귀 테스트 결과에 섞이는 것도 방지할 수 있습니다.
실패 결과를 다시 검토할 수 있게 만들기
실패한 작업에서는 최소한 세 가지 증거를 보관해야 합니다. xcresult, 픽스처 다이제스트, 해당 실행의 기기 정보입니다. 현재 사용 가능한 시뮬레이터 목록을 추가로 출력할 수는 있지만, 문제와 관련 없는 사용자 디렉터리 내용까지 수집해서는 안 됩니다.
흔한 오판과 대응 방법은 다음과 같습니다.
- 자산 수가 예상보다 많음: 작업 전에 시뮬레이터를 초기화하지 않았거나 여러 작업이 동일한 UDID를 재사용했습니다.
- 테스트에서 가끔 동영상을 찾지 못함: 가져온 직후 바로 조회해 사진 보관함 업데이트가 완료될 때까지 기다리지 않았습니다.
- 이미지의 너비와 높이가 뒤바뀜: 코드가 픽셀 크기를 읽을 때 방향 메타데이터를 무시했습니다.
- 로컬에서는 통과하지만 CI에서는 실패함: 테스트가 커밋되지 않은 파일, 기본 권한 또는 모호한 destination에 의존했습니다.
- 업로드 다이제스트가 달라짐: 앱이 리소스를 다시 인코딩했습니다. 입력 다이제스트와 업로드 본문의 다이제스트를 각각 기록해야 합니다.
작업이 끝나면 시뮬레이터를 종료합니다. 현재 작업에서 임시로 만든 기기라면 바로 삭제합니다. 장기간 유지하는 기기도 다음 작업 전에 다시 erase해야 하며, 사진 보관함 콘텐츠를 항목별로 삭제하는 방식에 의존해서는 안 됩니다. 최종 점검 항목은 픽스처 다이제스트 일치, UDID 단독 사용, 시스템 버전 고정, 명시적인 권한 상태, 가져오기 수량 대기 가능, 결과 번들 보관으로 정리할 수 있습니다. 이를 지키면 미디어 가져오기 실패에 안정적인 입력과 재검토 가능한 실행 현장이 확보됩니다.
자주 묻는 질문
simctl addmedia가 실제 기기 사진 테스트를 대체할 수 있나요?
완전히 대체할 수는 없습니다. 시뮬레이터의 검색, 선택, 읽기와 업로드 흐름에는 적합하지만 카메라 촬영, 기기별 코덱, 실제 저장 공간 압박은 기기 테스트가 필요합니다.
CI 실행 사이에 미디어가 누적되지 않게 하려면 어떻게 하나요?
작업마다 전용 시뮬레이터를 사용하고 주입 전에 shutdown과 erase를 실행한 뒤 테스트가 끝나면 임시 기기를 삭제합니다.
다음 빌드를 전용 Apple Silicon 물리 노드에서 실행
대여 기간과 노드 리전을 선택하고 Mac Mini M4, 16GB RAM, 256GB SSD 및 결제할 USD 금액을 확인한 뒤 주문을 제출하세요.