StoreKit 2 구독 테스트: 2026 세 가지 환경은 어떻게 선택할까?
📋 목차
구독 구매는 로컬에서 되는데 Sandbox에서 실패하고, TestFlight 빌드에서는 상태가 다르게 보입니까?
가장 빠른 해결책은 세 환경을 하나로 고르지 않는 것입니다. 초기 로직은 Xcode 로컬 테스트, 실제 상품과 서버 연동은 Sandbox, 출시 전 배포 경로는 TestFlight 순서로 검증하십시오.
이 글이 필요한 개발자
자동 갱신 구독을 처음 구현하는 개인 개발자라면 구매·복원·권리 상태를 어디서 먼저 확인할지 결정할 수 있습니다. App Store Connect 상품과 서버 알림을 이미 연결했다면 환경별 거래 검증 경계를 점검할 수 있습니다.
StoreKit 테스트를 원격 Mac이나 지속적 통합 환경으로 옮기려는 소규모 팀은 자동화할 작업과 사람이 직접 확인할 작업을 나눌 수 있습니다.
StoreKit 2 구독 테스트는 세 환경을 조합해야 합니다
세 환경은 같은 테스트의 난이도만 다른 변형이 아닙니다. 거래를 만드는 주체와 검증할 인프라가 다릅니다. Apple의 Sandbox 테스트 개요도 Xcode의 로컬 테스트, Sandbox, TestFlight를 서로 다른 검증 단계로 구분합니다.
| 환경 | 주로 검증할 대상 | 적합한 시점 | 통과해도 증명하지 못하는 것 |
|---|---|---|---|
| Xcode 로컬 테스트 | 구매·복원·만료·오류 등 앱 로직 | 상품 설정 전후의 초기 개발 | App Store 상품 등록과 서버 거래 흐름 |
| App Store Sandbox | 실제 상품 식별자와 App Store 서버 연동 | 상품과 서명된 개발 빌드가 준비된 뒤 | 최종 베타 설치와 외부 테스터 경험 |
| TestFlight | 업로드된 베타 빌드와 배포 경로 | 출시 전 최종 확인 | 운영 환경의 실제 결제 거래 |
이 표에서 가장 중요한 점은 “통과”의 범위입니다. 로컬 테스트가 통과했다는 뜻은 구성 파일을 기준으로 앱 코드가 예상 상태를 처리했다는 의미입니다. 운영 구독이 정상적으로 판매된다는 보증은 아닙니다.
원형 개발자는 로컬 테스트로 피드백을 짧게 만드십시오
아직 App Store Connect에 상품을 완성하지 않았다면 StoreKit 구성 파일을 먼저 사용하십시오. Xcode의 로컬 StoreKit Testing 설정 문서는 구성 파일을 만들고 앱의 테스트 구성으로 연결하는 절차를 설명합니다.
이 단계에서는 다음 흐름을 반복하는 것이 효율적입니다.
- 구독 상품의 식별자와 기간을 StoreKit 구성 파일에 정의합니다.
- 구매 버튼을 눌렀을 때 성공, 취소, 결제 오류를 각각 실행합니다.
- 앱을 삭제하거나 테스트 상태를 초기화한 뒤 복원 흐름을 확인합니다.
- 구독 권리가 활성 상태에서 만료 상태로 바뀔 때 화면 접근 권한을 확인합니다.
- StoreKitTest를 사용해 같은 시나리오를 자동 테스트로 고정합니다.
- 커밋마다 테스트 결과와 실패 로그를 저장합니다.
로컬 거래는 Xcode 테스트 환경이 생성합니다. 따라서 네트워크 상태나 App Store 상품 설정에 영향을 덜 받고, 실패 상태를 반복해서 재현하기 쉽습니다. 반대로 상품의 실제 판매 가능 여부, 서버가 받은 서명 거래의 처리, App Store Connect 설정 오류는 이 단계에서 발견하지 못할 수 있습니다.
Apple의 StoreKit Testing in Xcode 안내와 StoreKitTest 프레임워크 문서를 기준으로 테스트 시나리오를 작성하십시오. 특히 성공 거래 하나만 고정하면 자동화가 지나치게 낙관적인 결과를 냅니다.
상품과 서버가 연결되면 Sandbox로 검증 범위를 넓히십시오
다음 단계는 실제 상품 식별자와 App Store 서버가 참여하는 Sandbox입니다. 이 환경에서는 App Store Connect의 상품 상태, 개발 서명 빌드, 테스트 계정, 기기 설정이 함께 맞아야 합니다. 상품 설정 공식 안내에서 등록 상태를 확인하고, 구독 상품의 식별자를 앱 코드와 대조하십시오.
Sandbox로 넘어가기 전에 다음 항목을 확인하십시오.
- 앱의 Bundle ID와 상품 식별자가 서로 다른 환경의 값으로 섞이지 않았는지 확인합니다.
- 테스트에 사용할 Sandbox Apple Account를 공식 생성 절차에 따라 준비합니다.
- 개발 서명된 빌드에서 테스트 계정 로그인과 구매 요청을 분리해 확인합니다.
- 서버가 받은 거래의 환경 값을 운영 데이터와 분리합니다.
- App Store Server Notifications를 사용하는 경우 같은 알림이 다시 와도 권리가 중복 부여되지 않게 처리합니다.
- 테스트가 끝나면 계정, 상품 식별자, 거래 식별자를 운영 분석 자료와 섞지 않습니다.
Sandbox는 구매 실패, 갱신 상태 변화, 취소와 같은 App Store 서비스 상호작용을 확인하는 자리입니다. Sandbox 테스트 문서에 설명된 테스트 제어 항목을 기준으로 사용하되, 문서의 현재 화면과 계정 요구 사항이 다르면 작성 시점의 Apple 안내를 우선하십시오.
여기서 자주 생기는 오류는 로컬 구성 파일의 상품 식별자만 고친 뒤 Sandbox에서도 그대로 동작한다고 판단하는 것입니다. 로컬 거래는 구성 파일을 기준으로 생성되지만, Sandbox 거래는 등록된 상품과 서명된 앱, 테스트 계정을 함께 통과해야 합니다.
서버 중심 구독 개발자는 거래 상태를 두 번 승인해야 합니다
서비스 서버에서 JWS 거래를 검증하거나 여러 기기 사이에서 권리를 동기화한다면 로컬 테스트만으로는 부족합니다. 로컬 테스트는 앱이 거래 결과를 받아 화면과 로컬 권한을 바꾸는지 확인하는 데 유용하지만, App Store가 서명한 거래와 서버 알림의 실제 연결까지 완전히 재현하지는 않습니다.
이 역할의 검증 순서는 다음과 같습니다.
- 로컬 환경에서 앱의 구매·복원·만료 상태 처리를 자동화합니다.
- Sandbox에서 App Store 서버가 보낸 거래와 알림을 수신합니다.
- 서버가 환경 값을 확인한 뒤 Sandbox 데이터만 별도 저장하는지 확인합니다.
- 같은 거래나 알림이 반복되어도 멱등적으로 처리되는지 검사합니다.
- 갱신, 취소, 결제 실패 등 상태 전환마다 앱 권리와 서버 권리가 일치하는지 비교합니다.
- 검증이 끝난 테스트 데이터를 운영 지표와 삭제 또는 분리합니다.
- TestFlight 빌드에서 실제 앱 호출 경로와 서버 주소가 올바르게 연결되는지 확인합니다.
서버가 “유효한 서명”만 확인하고 환경을 검사하지 않으면 테스트 거래가 운영 권리로 잘못 들어갈 수 있습니다. 운영과 테스트용 서버 주소, 데이터베이스 영역, 로그 라벨을 분리하고, 거래 식별자는 문서와 로그에서 탈식별화하십시오.
Beta 배포자는 TestFlight를 마지막 검증층으로 사용하십시오
TestFlight의 역할은 초기 오류를 찾는 것이 아니라 업로드된 Beta 빌드가 실제 테스터 경로에서 작동하는지 확인하는 것입니다. TestFlight 구독 테스트 안내에 따르면 TestFlight 앱 내 구매는 Sandbox 환경에서 실행됩니다.
따라서 TestFlight는 다음 항목에 적합합니다.
- 아카이브와 업로드가 끝난 빌드가 올바르게 설치되는지 확인합니다.
- 로그인, 앱 최초 실행, 구매, 복원, 로그아웃 후 재로그인 흐름을 점검합니다.
- 베타 빌드가 올바른 상품 식별자와 서버 주소를 사용하는지 확인합니다.
- 외부 테스터가 안내받은 테스트 정보만으로 구매 흐름을 완료하는지 확인합니다.
- TestFlight 테스트 정보 요구 사항에 맞춰 테스터에게 필요한 설명을 제공합니다.
TestFlight가 Sandbox를 사용한다고 해서 Sandbox Apple Account의 모든 테스트 제어를 대신하는 것은 아닙니다. TestFlight는 배포된 빌드의 사용자 여정을 확인하는 데 초점을 둡니다. 고장 상태를 반복적으로 주입하거나 특정 거래 상황을 세밀하게 재현하는 작업은 앞선 로컬 테스트와 Sandbox에서 끝내야 합니다.
주의: TestFlight에서 구매가 성공해도 운영 결제와 운영 권리 처리가 검증된 것은 아닙니다. 테스트 환경 표식을 서버에서 확인하지 않은 채 운영 데이터에 저장하지 마십시오.
원격 Mac은 자동화와 수동 승인을 분리해야 합니다
상시 실행되는 원격 Mac은 StoreKitTest, 단위 테스트, 빌드, 로그 보관을 맡기기 좋습니다. 특히 로컬 컴퓨터를 끄거나 개발 환경을 바꾸어도 같은 커밋의 테스트 결과를 남길 수 있다는 장점이 있습니다.
다만 다음 작업을 모두 무인 자동화할 수 있다고 가정하면 안 됩니다.
- 실제 기기 연결과 기기 신뢰 승인
- 그래픽 세션이 필요한 Xcode 작업
- 테스트 계정 로그인과 계정 전환
- TestFlight 설치 및 외부 테스터 초대
- 인증서, 키체인, 서명 권한의 최초 승인
원격 Mac을 도입한다면 원격 Mac iOS 자동화 테스트 환경 구축 가이드처럼 실행 방식과 복구 경계를 먼저 정하십시오. 상시 빌드가 목적이라면 iOS 패키징 서버 검수 기준도 함께 확인할 수 있습니다.
같은 코드 커밋에 대해 로컬 테스트 결과, Sandbox 빌드 결과, TestFlight 빌드 결과를 각각 남기십시오. 하나의 성공 표시로 합치면 어느 환경에서 회귀가 발생했는지 추적하기 어렵습니다. 원격 환경의 안정성이나 성능을 일반화하지 말고, 실제 사용한 구성과 실행일을 기록해야 합니다.
세 역할별 선택 조건과 검증 중단선
아래 조건에서 현재 단계의 환경을 하나 고른 뒤, 다음 단계의 진입 조건이 충족될 때만 이동하십시오.
- 앱 화면과 권리 로직이 아직 바뀌고 있다면 Xcode 로컬 테스트를 선택하십시오. 구매, 복원, 만료, 오류 시나리오가 자동으로 재현될 때까지 Sandbox로 이동하지 마십시오.
- 상품 식별자와 App Store Connect 설정이 완료되었고 서버 거래 검증이 필요하다면 Sandbox를 선택하십시오. 테스트 환경 데이터가 운영 데이터와 분리되지 않았다면 TestFlight 배포를 멈추십시오.
- 업로드된 Beta 빌드의 설치와 외부 테스터 흐름을 확인해야 한다면 TestFlight를 선택하십시오. 로컬 상태 처리나 Sandbox 서버 검증이 아직 실패한다면 TestFlight를 최종 승인 단계로 사용하지 마십시오.
- 원격 Mac에서 반복 실행이 필요하다면 로컬 테스트 자동화부터 옮기십시오. 실제 기기와 TestFlight는 수동 승인 기록이 없으면 자동화 성공으로 판정하지 마십시오.
- 서버 알림을 처리한다면 로컬 테스트와 Sandbox를 함께 통과시킨 뒤 TestFlight로 이동하십시오. 환경 값, 멱등 처리, 상태 전환 중 하나라도 확인되지 않으면 출시 후보로 표시하지 마십시오.
환경별 준비물과 판정 기준 비교
| 구분 | 로컬 StoreKit Testing | App Store Sandbox | TestFlight |
|---|---|---|---|
| 앱 준비 | Xcode 프로젝트와 구성 파일 | 등록 상품과 개발 서명 빌드 | 업로드된 Beta 빌드 |
| 계정 요구 | 로컬 테스트 설정 | Sandbox 테스트 계정 | 테스터 배포 정보와 설치 경로 |
| 핵심 결과 | 클라이언트 로직 재현 | App Store 거래와 서버 연동 | 배포 빌드의 실제 사용 흐름 |
| 자동화 범위 | 높음 | 제한적 | 제한적 |
| 다음 단계 조건 | 상태 처리 자동 검증 | 운영·테스트 데이터 분리 | 출시 전 결함 없음 |
구독 상태별 검증 기록 비교
| 상태 | 앱에서 확인할 값 | 서버에서 확인할 값 | 기록해야 할 판정 |
|---|---|---|---|
| 신규 구매 | 활성 권리와 화면 잠금 해제 | 거래 서명과 환경 값 | 한 번만 권리 부여 |
| 복원 | 기존 권리 복구 | 기존 거래와 사용자 연결 | 중복 권리 생성 없음 |
| 갱신 | 권리 지속 또는 기간 변경 | 갱신 알림 반영 | 반복 알림에 안전함 |
| 만료·취소 | 유료 기능 차단 | 권리 종료 상태 저장 | 다음 실행에도 같은 결과 |
| 결제 오류·보류 | 오류 안내와 재시도 경로 | 서버 권리 보류 처리 | 실패를 성공으로 저장하지 않음 |
개발 단계별 선택 점수
점수는 비용이나 성능 평가가 아니라 현재 작업과 환경의 적합도를 나타냅니다. 각 행에서 가장 높은 점수를 우선 선택하되, 다음 검증층을 생략하지 마십시오.
| 작업 | 로컬 테스트 | Sandbox | TestFlight |
|---|---|---|---|
| 앱 상태 로직 반복 | 5 | 3 | 2 |
| 실제 상품 식별자 확인 | 1 | 5 | 4 |
| 서버 거래·알림 검증 | 2 | 5 | 4 |
| 업로드·설치·테스터 경로 | 1 | 2 | 5 |
| 원격 Mac 자동 실행 | 5 | 2 | 2 |
결론은 간단합니다. 초기 개발자는 로컬 테스트를 기본값으로 삼고, 실제 상품과 서버가 연결되는 순간 Sandbox를 추가하십시오. 출시 후보가 만들어지면 TestFlight에서 배포 경로를 확인하십시오. 세 환경을 동시에 구축하는 것보다 현재 단계의 실패 원인을 하나씩 닫는 편이 빠릅니다.
자주 묻는 경계 문제
로컬 테스트와 Sandbox의 차이는 거래 생성 주체와 검증 범위에 있습니다. TestFlight는 업로드된 Beta 빌드를 확인하는 층이며 Sandbox를 포함하지만 대체하지 않습니다. 원격 Mac은 반복 가능한 자동 작업을 맡을 수 있으나 계정과 실제 기기 절차까지 자동 성공으로 간주해서는 안 됩니다.
현재 사용 중인 컴퓨터가 StoreKitTest와 정기 빌드, 로그 보관을 오래 실행하기 어렵다면 MacDate의 원격 Mac 환경 안내에서 원격 실행 방식과 복구 조건을 먼저 살펴보십시오. 단기간 테스트라면 임시 환경이 맞을 수 있고, 계속 빌드와 로그를 유지해야 한다면 상시 환경이 더 적합할 수 있습니다.
자체 Mac을 계속 켜 두는 방식은 전력과 저장 공간, 운영체제 업데이트, 원격 복구를 직접 관리해야 합니다. 일반 클라우드 빌드는 그래픽 세션과 실제 macOS 도구 체인 접근이 제한될 수 있고, Windows나 Linux 환경만으로는 Xcode와 서명 단계가 해결되지 않습니다. 이런 제약이 있는 개발자라면 MacDate의 Mac 원격 임대 환경으로 StoreKitTest, 빌드, 로그 보관을 분리해 운영하는 편이 더 현실적입니다. 단, 실제 기기와 TestFlight 계정 승인은 여전히 별도로 진행해야 합니다.