Test Store Genel Bakis

0:02:00

iOS icin RevenueCat Test Store kurulum kilavuzuna hos geldiniz!

Uygulama ici satin alma testleri her zaman zor olmustur. Sandbox hesaplari kurmak, test urunleri olusturmak, uygulama incelemelerini beklemek ve guvenilmez ag kosullarini yonetmek gerekiyordu. RevenueCat'in Test Store'u belirleyici, hizli ve guvenilir bir test ortami saglayarak bu sorunlari cozer.

Test Store Nedir?

Test Store, App Store'a baglanmadan uygulama ici satin alma akislarini test etmenizi saglayan RevenueCat'in yerlesik test ortamidir. Tum yeni RevenueCat projelerine otomatik olarak saglanir ve satin alma sonuclari uzerinde tam kontrol sunar.

Ogrenecekleriniz

Bu codelab'de iOS gelistirme icin RevenueCat'in Test Store kurulumu ve kullaniminin tum surecini ogreneceksiniz. RevenueCat panelinde Test Store'u etkinlestirmek ve iOS uygulamanizi Test Store API anahtarini kullanacak sekilde yapilandirmakla baslayacaksiniz. Ardindan belirleyici sonuclarla satin alma akislarini test etmeyi, uygulama ici satin alma mantigi icin otomatik birim testleri yazmayi ve GitHub Actions kullanarak bu testleri CI/CD pipeline'iniza entegre etmeyi ogreneceksiniz.

Test Store'un Avantajlari

Test Store, uygulama ici satin alma test yontemini devrim niteliginde degistiriyor. App Store Connect yapilandirmasi veya uygulama onayini beklemenizi gerektiren mevcut test yontemlerinin aksine, Test Store anlik test yetenekleri sunar. Satin alma sonuclari uzerinde tam belirleyici kontrol saglar. Islemin basarili olup olmayacagi, basarisiz olup olmayacagi veya iptal edilip edilmeyecegi tamamen size baglidir. Bu, guvenilmez ag baglantilari veya guvenilmez sandbox ortamlariyla ugrasmaniza gerek olmadigini gosterir.

Gercek guc, otomatik testler yazmayi baslattiginizda ortaya cikar. Test Store'u kullanarak GitHub Actions gibi CI/CD sistemleri dahil tum ortamlarda tutarli olarak calisan satin alma mantigi icin guvenilir birim testleri olusturabilirsiniz. Bu sayede satin alma akislarini hizla yineleyerek degisiklikleri dakikalar veya saatler yerine saniyeler icinde test edebilirsiniz.

overview

On Kosullar

Baslamadan once asagidakileri kontrol edin:

  1. RevenueCat hesabi (revenuecat.com'da ucretsiz)
  2. RevenueCat SDK entegre edilmis iOS projesi (surum 5.x veya ustu)
  3. Swift ve iOS gelistirme hakkinda temel bilgi
  4. SwiftUI hakkinda anlayis (istege bagli, UI ornekleri icin)

Panelde Test Store'u Etkinlestirme

0:03:00

Ilk adim, RevenueCat panelinde Test Store'u etkinlestirmek ve Test Store API anahtarini almaktir.

Panele Erisim

RevenueCat paneline giris yapin ve sol kenar cubugu menusundeki Apps & providers bolumune gidin. Burada bagli tum uygulamalarinizi ve mevcut magaza entegrasyonlarinizi bulabilirsiniz.

Test Store Olusturma

Apps & providers bolumunde mevcut saglayicilar arasinda Test Store secenegini bulun. Test Store tum RevenueCat projelerine otomatik olarak saglandigi icin Create Test Store veya Enable Test Store'a tiklayarak etkinlestirmeniz yeterlidir. Kurulum onayi veya yapilandirma senkronizasyonu beklemenize gerek yoktur; aninda tamamlanir.

API Anahtarini Alma

Test Store etkinlestirildiginde, uygulama listesinde Test Store girisine tiklayarak ayrintilari kontrol edin. Burada test_ onekiyle baslayan Test Store API Key'i bulabilirsiniz. Bu anahtar normal RevenueCat API anahtari gibi calisir, ancak onemli bir fark vardir: tum satin alma isteklerini App Store yerine Test Store'a yonlendirerek test ortami uzerinde tam kontrol saglar.

API Anahtari Ayrimini Anlama: Test Store API anahtari, production ve sandbox anahtarlarindan tamamen ayridir. Bu ayrim kasitli ve guvenlik acisindan onemlidir. Production build'lerde asla Test Store anahtarini kullanmayin; yalnizca debug ve test ortamlarinda kullanin. Gerekirse farkli test senaryolari icin proje basina birden fazla Test Store yapilandirmasi olusturabilirsiniz.

test-store-setup

Sonraki Adim

Artik Test Store API anahtarini aldiginiza gore, iOS uygulamanizi test icin Test Store'u kullanacak sekilde yapilandirmaya hazirsiniz.

iOS Uygulamada Test Store Kurulumu

0:05:00

Simdi iOS uygulamanizi Test Store'u kullanacak sekilde yapilandiracagiz. Onemli olan, testleri calistirirken production API anahtari yerine Test Store API anahtarini kullanmaktir.

Adim 1: Xcode Yapilandirmasi ile Test Store API Anahtari Ekleme

API anahtarlarinizi yapilandirma bazinda yonetmek icin bir xcconfig dosyasi olusturun veya Xcode build ayarlarini kullanin. Debug.xcconfig adinda bir dosya olusturun:

text
// Debug.xcconfig
REVENUECAT_API_KEY = test_YOUR_KEY_HERE

Ve bir Release.xcconfig:

text
// Release.xcconfig
REVENUECAT_API_KEY = appl_YOUR_PRODUCTION_KEY

Ardindan Info.plist dosyaniza REVENUECAT_API_KEY ekleyin:

xml
<key>RevenueCatAPIKey</key>
<string>$(REVENUECAT_API_KEY)</string>

Adim 2: Uygulamada SDK Baslatma

RevenueCat'i uygun API anahtariyla yapilandirmak icin @main App struct'inizi guncelleyin:

swift
import RevenueCat
import SwiftUI

@main
struct MyApp: App {
    init() {
        // Read API key from Info.plist (set via xcconfig)
        let apiKey = Bundle.main.infoDictionary?["RevenueCatAPIKey"] as? String
            ?? "test_YOUR_KEY_HERE"

        Purchases.configure(withAPIKey: apiKey)

        // Enable debug logs for test builds
        #if DEBUG
        Purchases.logLevel = .debug
        #endif
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Adim 3: Ortama Ozel Yapilandirma

Gelismis yapilandirmalar icin #if DEBUG onislemci yonergelerini kullanarak bir yapilandirma yardimcisi olusturabilirsiniz:

swift
enum RevenueCatConfig {
    static var apiKey: String {
        #if DEBUG
        return "test_YOUR_KEY_HERE"
        #else
        return "appl_YOUR_PRODUCTION_KEY"
        #endif
    }

    static func configure() {
        Purchases.configure(withAPIKey: apiKey)

        #if DEBUG
        Purchases.logLevel = .verbose
        #endif
    }
}

Ardindan uygulama baslatma sirasinda kullanin:

swift
@main
struct MyApp: App {
    init() {
        RevenueCatConfig.configure()
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Dogrulama

Test Store'un calisip calismadigini dogrulamak icin:

  1. Uygulamayi Xcode'da debug modunda calistirin
  2. Xcode konsolunda "Purchases SDK initialized with Test Store" mesajini kontrol edin
  3. SDK'nin App Store yerine Test Store'a baglandigini dogrulayin
test-store-config

Etkilesimli Satin Alma Akisi Testi

0:05:00

Test Store etkinlestirildiginde, artik sonuclari tam olarak kontrol ederek satin alma akislarini test edebilirsiniz. Test Store satin alma iletisim kutusunu gosterdiginde sonucu siz belirlersiniz.

Test Store Satin Alma Iletisim Kutusunu Anlama

Test Store ile bir satin alma baslattiginizda, standart App Store satin alma sayfasi yerine ozel bir Test Store iletisim kutusu gosterilir. Bu iletisim kutusu, gercek satin alma iletisim kutusu gibi urun ayrintilari ve fiyatlandirmayi gosterir, ancak onemli bir fark vardir: sonucu kontrol edebilirsiniz. Iletisim kutusu uc net secenek sunar: tamamlanmis islemi simule eden Successful Purchase, satin alma basarisizligini test eden Failed Purchase ve kullanici iptalini simule eden Cancel. Bu belirleyici davranis, Test Store'u test icin son derece guclu kilan seydir.

Basarili Akisi Test Etme

Basarili bir satin alma akisini test edelim:

swift
func purchaseProduct() async {
    do {
        // Fetch products from Test Store
        let offerings = try await Purchases.shared.offerings()

        guard let package = offerings.current?.availablePackages.first else {
            return
        }

        // Initiate purchase
        let (_, customerInfo, _) = try await Purchases.shared.purchase(package: package)

        // Check the result
        let isPremium = customerInfo.entitlements["premium"]?.isActive == true

        if isPremium {
            // Purchase successful!
            showPremiumContent()
        }
    } catch {
        // Handle error
        handlePurchaseError(error)
    }
}

Mutlu Yol Testi: Uygulamayi calistirin ve her zamanki gibi satin alma akisini baslatin. Test Store iletisim kutusu gorundigunde "Successful Purchase"'a dokunun. Uygulama aninda premium erisim vermeli ve yetkinin dogru guncellendigini dogrulayabilirsiniz. Bu sayede gercek odeme yontemi veya sandbox hesabi olmadan basarili akisin dogru calisip calismadigini hizlica kontrol edebilirsiniz.

Basarisiz Senaryolari Test Etme

Simdi uygulamanizin basarisizliklari nasil isledigini test edin:

swift
func handlePurchaseError(_ error: Error) {
    guard let purchasesError = error as? RevenueCat.ErrorCode else {
        showError("Unexpected error: \(error.localizedDescription)")
        return
    }

    switch purchasesError {
    case .purchaseCancelledError:
        // User cancelled - don't show error
        print("User cancelled purchase")
    case .purchaseInvalidError:
        // Invalid purchase
        showError("This purchase is not available")
    case .paymentPendingError:
        // Payment pending (e.g., awaiting parental approval)
        showPendingMessage()
    default:
        // Other errors
        showError("Purchase failed: \(error.localizedDescription)")
    }
}

Hata Isleme Testi: Satin alma akisini tekrar baslatin, ancak bu sefer Test Store iletisim kutusu gorundigunde "Failed Purchase"'a dokunun. Uygulama hatayi duzgun sekilde islemeli ve kullaniciya uygun bir hata mesaji gostermelidir. Kullanicinin premium erisim almadigini ve uygulamanin durumunun tutarli kaldigini dogrulayin. Bu, production'da hata isleme mantginizin dogru calisip calismadigini kontrol etmek icin onemlidir.

Iptali Test Etme

swift
struct PaywallView: View {
    @State private var isPurchasing = false
    var onDismiss: () -> Void

    var body: some View {
        Button(action: {
            Task {
                isPurchasing = true
                do {
                    try await purchaseProduct()
                } catch let error as RevenueCat.ErrorCode
                    where error == .purchaseCancelledError {
                    // User cancelled - just dismiss
                    onDismiss()
                } catch {
                    // Handle other errors
                    handlePurchaseError(error)
                }
                isPurchasing = false
            }
        }) {
            Text(isPurchasing ? "Processing..." : "Subscribe")
        }
        .disabled(isPurchasing)
    }
}

Kullanici Iptali Testi: Odeme duvarini acin ve abonelik butonuna dokunun. Test Store iletisim kutusu gorundigunde, satin almayi iptal eden bir kullaniciyi simule etmek icin "Cancel"'a dokunun. Odeme duvari hata mesaji gostermeden temiz bir sekilde kapanmalidir (iptal, bir hata durumu degil, normal bir kullanici eylemidir). Satin alma islemi kaydedilmedigini ve uygulamanin durumunun degismedigini dogrulayin.

Temel Cikarimlar

Test Store'un gucu belirleyici kontroldedir. Her satin alma girisiminde tam olarak ne olacagina siz karar verirsiniz. Bu, gercek odeme yontemi gerektirmeden veya sandbox hesaplarinin gecikmeleri ve karmasikliklarini yonetmeden dakikalar icinde tum senaryolari (basarili, basarisiz ve iptal) kapsamli bir sekilde test edebileceginiz anlamina gelir. App Store ile entegre etmeye hazir oldugunuzda, satin alma mantginizin saglam olduguna dair tam bir guven duyabilirsiniz.

test-store-testing

Otomatik Birim Testleri Yazma

0:08:00

Test Store'un en guclu ozelliklerinden biri, uygulama ici satin alma mantigi icin otomatik birim testleri yazmanizi saglamasidir. CI/CD'de guvenilir bir sekilde calisan testler yazalim.

Adim 1: XCTest Kurulumu

XCTest, Xcode'a yerlesiktir, bu nedenle harici bagimliliklara gerek yoktur. Projenizde bir test hedefi oldugundan emin olun. Xcode'un varsayilan proje sablonunu kullandiysaniz zaten dahil edilmistir. Package.swift veya Xcode projenizde RevenueCat zaten bir bagimlilik olarak bulunmalidir:

swift
// In your Package.swift or via Xcode SPM
dependencies: [
    .package(url: "https://github.com/RevenueCat/purchases-ios.git", from: "5.58.0")
]

Adim 2: Purchase Repository Protokolu Olusturma

Oncelikle Swift protokolu kullanarak test edilebilir bir purchase repository olusturalim:

swift
protocol PurchaseRepository {
    func getOfferings() async throws -> Offerings
    func purchase(package: Package) async throws -> CustomerInfo
    func getCustomerInfo() async throws -> CustomerInfo
}

final class PurchaseRepositoryImpl: PurchaseRepository {

    func getOfferings() async throws -> Offerings {
        return try await Purchases.shared.offerings()
    }

    func purchase(package: Package) async throws -> CustomerInfo {
        let (_, customerInfo, _) = try await Purchases.shared.purchase(package: package)
        return customerInfo
    }

    func getCustomerInfo() async throws -> CustomerInfo {
        return try await Purchases.shared.customerInfo()
    }
}

Adim 3: Is Mantigi Iceren ViewModel Olusturma

swift
enum PaywallState {
    case loading
    case success(packages: [Package])
    case purchasing
    case purchaseSuccess
    case purchaseCancelled
    case error(message: String)
}

@MainActor
final class PaywallViewModel: ObservableObject {
    @Published var state: PaywallState = .loading

    private let repository: PurchaseRepository

    init(repository: PurchaseRepository) {
        self.repository = repository
    }

    func loadProducts() async {
        do {
            let offerings = try await repository.getOfferings()
            let packages = offerings.current?.availablePackages ?? []
            state = .success(packages: packages)
        } catch {
            state = .error(message: error.localizedDescription)
        }
    }

    func purchase(package: Package) async {
        state = .purchasing
        do {
            let customerInfo = try await repository.purchase(package: package)
            let isPremium = customerInfo.entitlements["premium"]?.isActive == true

            if isPremium {
                state = .purchaseSuccess
            } else {
                state = .error(message: "Purchase completed but entitlement not active")
            }
        } catch let error as RevenueCat.ErrorCode
            where error == .purchaseCancelledError {
            state = .purchaseCancelled
        } catch {
            state = .error(message: error.localizedDescription)
        }
    }
}

Adim 4: XCTest ile Birim Testleri Yazma

Simdi mock repository kullanarak birim testleri olusturun:

swift
import XCTest
@testable import MyApp

final class MockPurchaseRepository: PurchaseRepository {
    var mockOfferings: Offerings?
    var mockCustomerInfo: CustomerInfo?
    var mockError: Error?

    func getOfferings() async throws -> Offerings {
        if let error = mockError { throw error }
        return mockOfferings!
    }

    func purchase(package: Package) async throws -> CustomerInfo {
        if let error = mockError { throw error }
        return mockCustomerInfo!
    }

    func getCustomerInfo() async throws -> CustomerInfo {
        if let error = mockError { throw error }
        return mockCustomerInfo!
    }
}

@MainActor
final class PaywallViewModelTests: XCTestCase {

    private var mockRepository: MockPurchaseRepository!
    private var viewModel: PaywallViewModel!

    override func setUp() async throws {
        mockRepository = MockPurchaseRepository()
        viewModel = PaywallViewModel(repository: mockRepository)
    }

    func testPurchaseSuccess() async {
        // Given: Mock successful purchase with active entitlement
        // Set up mockCustomerInfo with active "premium" entitlement

        // When: Purchase is initiated
        // await viewModel.purchase(package: mockPackage)

        // Then: State should be purchaseSuccess
        // XCTAssertEqual(viewModel.state, .purchaseSuccess)
    }

    func testPurchaseCancelled() async {
        // Given: Mock cancelled purchase
        mockRepository.mockError = RevenueCat.ErrorCode.purchaseCancelledError

        // When: Purchase is initiated
        // await viewModel.purchase(package: mockPackage)

        // Then: State should be purchaseCancelled
        // XCTAssertEqual(viewModel.state, .purchaseCancelled)
    }

    func testPurchaseFailed() async {
        // Given: Mock failed purchase
        mockRepository.mockError = RevenueCat.ErrorCode.paymentPendingError

        // When: Purchase is initiated
        // await viewModel.purchase(package: mockPackage)

        // Then: State should be error
        // if case .error(let message) = viewModel.state {
        //     XCTAssertTrue(message.contains("pending"))
        // } else {
        //     XCTFail("Expected error state")
        // }
    }
}

Adim 5: Mock Tabanli Test Alternatifi

Daha fazla kontrol icin tamamen mock tabanli bir yaklasim kullanabilirsiniz:

swift
final class SpyPurchaseRepository: PurchaseRepository {
    var getOfferingsCalled = false
    var purchaseCalled = false
    var lastPurchasedPackage: Package?

    var stubbedOfferings: Offerings!
    var stubbedCustomerInfo: CustomerInfo!
    var stubbedError: Error?

    func getOfferings() async throws -> Offerings {
        getOfferingsCalled = true
        if let error = stubbedError { throw error }
        return stubbedOfferings
    }

    func purchase(package: Package) async throws -> CustomerInfo {
        purchaseCalled = true
        lastPurchasedPackage = package
        if let error = stubbedError { throw error }
        return stubbedCustomerInfo
    }

    func getCustomerInfo() async throws -> CustomerInfo {
        if let error = stubbedError { throw error }
        return stubbedCustomerInfo
    }
}

Bu Yaklasim Neden Calisiyor

Bu test yaklasimi, uygulama ici satin alma testinin geleneksel sorunlarini ortadan kaldirir. Test Store'a ag bagimliligi olmadigindan testler her seferinde guvenilir bir sekilde calisir. Artik baglanti sorunlari nedeniyle tutarsiz basarisizliklar yasamazsiniz. Testler dakikalar yerine saniyeler icinde calisarak gelistirme sirasinda hizli geri bildirim saglar. Gercek satin alma sistemleriyle yeniden uretmesi zor veya zaman alici uc durumlar dahil tum senaryolarda tam test kapsamini elde edebilirsiniz.

Olusturdugumuz mimari (is mantgini SDK'dan ayiran protokol deseni kullanarak) bu testleri hizli ve bakimi kolay kilar. GitHub Actions gibi herhangi bir CI/CD ortaminda calistirabilirsiniz, boylece production'a ulasmadan once hatalari yakalayabilirsiniz.

CI/CD'de Testleri Calistirma

0:04:00

Simdi testlerin GitHub Actions'da otomatik olarak calismasini ayarlayacagiz, boylece her kod degisikliginde satin alma mantigi tutarli bir sekilde korunur.

Adim 1: GitHub Actions Workflow Olusturma

.github/workflows/ios-tests.yml dosyasini olusturun:

yaml
name: iOS Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]

jobs:
  test:
    runs-on: macos-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Select Xcode version
        run: sudo xcode-select -s /Applications/Xcode.app

      - name: Cache SPM packages
        uses: actions/cache@v3
        with:
          path: |
            ~/Library/Developer/Xcode/DerivedData
            .build
          key: ${{ runner.os }}-spm-${{ hashFiles(&#039;**/Package.resolved') }}
          restore-keys: |
            ${{ runner.os }}-spm-

      - name: Run unit tests
        env:
          REVENUECAT_TEST_STORE_API_KEY: ${{ secrets.REVENUECAT_TEST_STORE_API_KEY }}
        run: |
          xcodebuild test \
            -scheme MyApp \
            -destination &#039;platform=iOS Simulator,name=iPhone 15,OS=latest' \
            -resultBundlePath TestResults.xcresult \
            REVENUECAT_API_KEY=$REVENUECAT_TEST_STORE_API_KEY

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-results
          path: TestResults.xcresult

Adim 2: GitHub Secrets'a Test Store API Anahtarini Ekleme

  1. GitHub repository'nize gidin
  2. SettingsSecrets and variablesActions bolumune gidin
  3. New repository secret'a tiklayin
  4. Ad: REVENUECAT_TEST_STORE_API_KEY
  5. Deger: Test Store API anahtariniz (ornegin: test_xxxxx)
  6. Add secret'a tiklayin

Adim 3: Secret'i Kullanmak icin Xcode Yapilandirmasi

Ortam degiskeni mevcut oldugunda okumak icin xcconfig dosyanizi guncelleyin:

text
// Debug.xcconfig
// Use environment variable if available (CI), fallback to local key
REVENUECAT_API_KEY = $(REVENUECAT_API_KEY:default=test_YOUR_KEY_HERE)

Adim 4: Fastlane Alternatifi

iOS CI/CD icin Fastlane kullaniyorsaniz bir test lane'i ekleyebilirsiniz:

ruby
lane :test do
  run_tests(
    scheme: "MyApp",
    devices: ["iPhone 15"],
    result_bundle: true,
    xcargs: "REVENUECAT_API_KEY=#{ENV['REVENUECAT_TEST_STORE_API_KEY']}"
  )
end

Kurulumu Dogrulama

Degisiklikleri commit ve push ederek workflow'u tetikleyin. Repository'nizin GitHub Actions sekmesine giderek testlerin otomatik olarak calistigini dogrulayin. Workflow kodu checkout ederken, macOS ortamini kurarken ve test paketini calistirirken gercek zamanli ilerlemeyi gorebilirsiniz. Birkac dakika icinde CI ortaminda tum testlerin gecip gecmedigini ogreneceksiniz.

Otomatik Testlerin Gucu

Bir kez kuruldugunda, her pull request birlestirilmeden once otomatik olarak dogrulanir. Bir degisiklik satin alma mantgini bozarsa aninda geri bildirim alirsiniz ve tum senaryolari manuel olarak test etmeniz gerekmez. Test Store, her calistirmada testlerin tutarli sonuclar uretmesini saglar ve tutarsiz testlerin hayal kirikligini ortadan kaldirir. Bu, hatali kodun main branch'e ulasmasini engelleyen bir kalite kapisi olusturur ve tekrarlayan manuel testlere harcanacak sayisiz saat tasarruf saglar.

En Iyi Uygulamalar ve Production Kurulumu

0:03:00

Test Store'u kurdugunuza gore, simdi en iyi uygulamalari ve Test Store ile production ortami arasinda nasil gecis yapacaginizi ele alacagiz.

Ortam Ayirimi

Test Store ve production anahtarlarini her zaman #if DEBUG kullanarak ayri tutun:

swift
enum RevenueCatKeys {
    // Test Store - for testing only
    static let testStoreKey = "test_xxxxx"

    // App Store - for production
    static let appStoreKey = "appl_xxxxx"

    static var apiKey: String {
        #if DEBUG
        return testStoreKey
        #else
        return appStoreKey
        #endif
    }
}

Xcode Scheme/Yapilandirma Tabanli Anahtar Degistirme

Daha ayrintili kontrol icin Xcode build yapilandirmalarini kullanin:

text
// Debug.xcconfig (Test Store)
REVENUECAT_API_KEY = test_xxxxx
USE_TEST_STORE = YES

// Staging.xcconfig (Test Store)
REVENUECAT_API_KEY = test_xxxxx
USE_TEST_STORE = YES

// Release.xcconfig (App Store)
REVENUECAT_API_KEY = appl_xxxxx
USE_TEST_STORE = NO

Kapsamli Bir Test Stratejisi Olusturma

Uygulama ici satin almalar icin saglam bir test stratejisi piramit yaklasimini izlemelidir. Test Store kullanarak birim testleriyle baslayin ve satin alma mantgini izole olarak dogrulayin. Bunlar hizli calisir ve cogu sorunu erkenden yakalar. Bu temel uzerine, yine Test Store kullanan entegrasyon testleri olusturarak tam satin alma akisini uctan uca kontrol edin. Uygulamaniza guvendiginizde, platform entegrasyonunu kontrol etmek icin Apple Sandbox ile manuel teste gecin. Son olarak, canli ortamda her seyin calistigini dogrulamak icin gercek satin almalarla kucuk olcekli production testleri yapin.

Test Store ve Apple Sandbox Arasinda Secim Yapma

Erken gelistirme ve yineleme sirasinda Test Store en iyi seciminizdir. Satin alma akislarinin hizli prototiplenmesi, birim ve entegrasyon testleri yazma, hata isleme ve uc durum testleri icin mukemmeldir. Anlik geri bildirim dongusu, guvenilir ve hizli sonuclar gerektiren CI/CD otomatik testleri icin idealdir.

Test Store'un simule etmedigi platforma ozgu ozellikleri test etmeniz gerektiginde Apple Sandbox'a gecin. Buna bekleyen islemler (ornegin Ask to Buy onayi bekleme), makbuz dogrulama ayrintilari, abonelik yenileme donguleri ve bolgeye ozgu fiyatlandirma dahildir. Sandbox'i production oncesi dogrulama ortami olarak dusunun. Temel mantginizin saglam oldugunu bildiginizde ve App Store entegrasyonunu kontrol etmeniz gerektiginde kullanin.

Guvenlik En Iyi Uygulamalari

Production'da asla Test Store API anahtarini ifsa etmeyin:

swift
// ❌ BAD: Hardcoded keys
let apiKey = "test_xxxxx"

// ✅ GOOD: Compile-time configuration
#if DEBUG
let apiKey = "test_xxxxx"
#else
let apiKey = "appl_xxxxx"
#endif

// ✅ BETTER: Read from xcconfig via Info.plist
let apiKey = Bundle.main.infoDictionary?["RevenueCatAPIKey"] as! String

Loglama ve Hata Ayiklama

Uygun loglama seviyelerini etkinlestirin:

swift
#if DEBUG
Purchases.logLevel = .verbose
print("RevenueCat: Using Test Store for testing")
#else
Purchases.logLevel = .info
#endif

Production'a Gecis

Uygulamanizi yayinlamadan once kapsamli bir kontrol listesini tamamladiginizdan emin olun. Tum testler Test Store ile gecmeli ve Apple Sandbox ile entegrasyon manuel olarak dogrulanmalidir. Xcode yapilandirmalarinin her ortamda dogru API anahtarini kullanacak sekilde dogru ayarlandigini tekrar kontrol edin. Production API anahtari guvenli tutulmali ve surum kontrolune commit edilmemelidir. Test Store anahtarinin release build'lerden tamamen kaldirildigini dogrulayin; yalnizca debug yapilandirmasinda bulunmalidir. Loglamanin uygun sekilde ayarlandigini kontrol edin (debug'da ayrintili, production'da minimum). Tum senaryolarda hata islemenin test edildigini dogrulayin.

Sonuc

Tebrikler! iOS icin RevenueCat'in Test Store'unu basariyla kurdunuz. Bu codelab'de RevenueCat panelinde Test Store'u etkinlestirmeyi, iOS uygulamanizda Test Store API anahtarini yapilandirmayi, belirleyici sonuclarla satin alma akislarini test etmeyi, satin alma mantigi icin otomatik birim testleri yazmayi, GitHub Actions gibi CI/CD ortamlarinda bu testleri calistirmayi ve ortam ayirimi icin en iyi uygulamalari ogrendiniz.

Temel Cikarimlar

Test Store, uygulama ici satin alma testine yaklasim sekilinizi temelden degistirir. Sandbox hesaplariyla ugrasma ve tutarsiz aga bagli testlerle bas etme gunleri geride kaldi. Satin alma sonuclari uzerinde belirleyici kontrol sayesinde uygulamaniza gercek guven veren guvenilir testler yazabilirsiniz. CI/CD entegrasyonu, her kod degisikliginde satin alma mantginin surekli dogrulandigini gosterir ve satin alma akislarini saatler yerine saniyeler icinde yineleyebilirsiniz. En onemlisi, satin almayla ilgili hatalari production'a ulasmadan once yakalayarak hem gelirinizi hem de kullanici deneyimini koruyabilirsiniz.

Sonraki Adimlar

Artik Test Store'u kurdugunuza gore, bu temel uzerine insa etme zamani. Tum satin alma senaryolarini kapsayan kapsamli testler yazarak baslayin; sadece mutlu yolu test etmeyin. Bu testleri CI/CD pipeline'iniza entegre edin, boylece her pull request'te otomatik olarak calisirlar. Uygulamanizin duzgun bir sekilde bozulup bozulmadigini kontrol etmek icin cesitli basarisizlik modlariyla hata islemeyi kapsamli bir sekilde test edin. Hazir oldugunuzda, abonelik yenilemeleri gibi seyleri kontrol etmek icin platforma ozgu testler icin Apple Sandbox'a gecin. Son olarak, satin alma mantginizin her adimda kapsamli bir sekilde dogrulandigini bilerek guvenle yayinlayin.

Ek Kaynaklar

RevenueCat Test Store Blog Yazisi RevenueCat iOS SDK Belgeleri Test Kilavuzu GitHub: purchases-ios

Iyi testler!