[UnitTest]StoreKitTest を使って、In-App Purchase をテストする方法

StoreKitTest を使ったテストの方法を紹介します

StoreKit

すでに使われたプロジェクトがある前提で説明します。

非同期処理を含んだテストになるので、XCTestCase 側で 以下のタイミングを知ることができる必要があります。

  • ProductRequest が終了したタイミング
  • PaymentQueu の Transaction の処理が終了したタイミング

テストの内容

以下の内容の UnitTest を実装していきます。

  • AppStore 側から、登録してあるはずの SKProduct 情報がきちんと取得できるか
  • 購入処理をすると、アプリ内部の購入済みフラグが、true にセットされるか
  • 外部購入していると、アプリ起動時に内部の購入済みフラグが適切にセットされるか(購入履歴あり・なし の2ケース)
  • 返金処理をすると、アプリ内部の購入済みフラグが、false にセットされるか

Subscription 等は、複雑になりそうなので、必要性に応じて。

テスト対象コード

Store というクラスを作り、StoreKit とのやり取りをまとめました(WWDC2020 を真似てます)

Store code

このクラスに対してのテストを作っていきます。

テストのポイント

  • 非同期処理のため、適宜、「待つ」必要があります
  • 処理によって、XCTestExpectation を .fulfill するのは、Delegate だったり、observer だったりします

テストコード

製品情報が取得できているか

まずは、製品情報(SKProduct)が正しく取得できるかのテストを作ります。

製品情報は非同期で読み込まれますので、delegate 内で、処理完了を待ちます。

example code
コード解説
  1. テスト用の Session を作ります。Configuration.storekit というコンフィグレーションを使うことを指定しています。
  2. ユーザーとのやり取りなしに進めることを指定します
  3. テスト前にトランザクションをクリアしています
  4. テスト用の Store を作成しています
  5. テスト用の Session に対しての設定をリセットします
  6. 製品情報は、非同期で読み込ませるために、終了を待つための XCTestExpectation を作成し、読み込み終了時に、 fulfill しています。
  7. XCTestExpectation が fulfill されるまで待ちます。
  8. Store を生成し、製品情報を読み込ませています。
  9. 製品情報 読み込み後に、期待通りの製品が2つ登録されていることをテストしています

製品を購入処理して、フラグがアップデートされるか

アプリ内で、購入処理をした時に、購入済みであることを表すフラグが正しくアップデートされるかをテストします。

製品購入も非同期で処理されます。製品購入については、observer をセットできますので、その中で、処理完了のフラグをセットします。

内部購入処理テスト code
コード解説
  1. 自身を SKPaymentQueue の Observer として登録します( SKPaymentTransactionObserver に extension で準拠させています)
  2. アプリコードとしての購入処理です。次の行の wait で購入処理が終わるのを待っています
  3. session に登録された transaction があることを確認します
  4. session に登録された transaction が購入処理であり、対象の製品 ID に対する購入が終わっていることをテストします
  5. アプリ内で保持している購入済み情報をテストしています
  6. 購入済み情報が、item1 についての情報であることをテストしています

外部購入していると、アプリ起動時に内部の購入済みフラグが適切にセットされるか

アプリ外で購入された時に、アプリ起動時に処理をし、購入済みであることを表すフラグが正しくアップデートされるかをテストします。

外部購入処理テスト code
コード解説
  1. SKTestSession の buyProduct をコールし、外部購入を模擬しています
  2. session に購入transaction が作られていることをテストしています
  3. 結果として、アプリ内でも item1 が購入されたフラグが設定されていることをテストしています
  4. 外部で購入されていない前提なので、transaction が 0 であることをテストしています
  5. 購入済みフラグが設定されていないことをテストしています

Refund 処理のテスト

SKTestSession の refundTransaction が期待通りに動かないです・・・・

refundTransaction をコールすると、新しい Transaction が Session に登録されることを期待しているのですが、refundTransaction コールの前後で、(refund 対象となる予定の)購入 transaction のみが、session に含まれるだけです。session が変化しません。

自分の環境依存なのか、期待値が間違っているのかがわかりません。

わかりましたら、アップデートします。

まとめ:StoreKitTest を使って、In-App Purchase をテストする方法

StoreKitTest を使って、In-App Purchase をテストする方法
  • XCTestSession を使って、購入全体を管理します
  • XCTestExpectation を使って、待つ必要がある
  • 適宜、Delegate, Observer を使って、処理が完了されることを待つ

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です