mcpField
R
rc-testing

rc-testing

github.com/revenuecatテスト・品質76648 回インストール1 日前に更新
リポジトリ

rc-testing について

rc-testing は、RevenueCat のテスト手順を整える Android 開発者向けスキルです。Test Store による購入結果の検証に加え、BillingService、mockk、GitHub Actions を使った単体テストと CI を扱います。

主な機能

  1. 01Test Store で購入結果をテスト
  2. 02BillingService で Purchases をラップ
  3. 03mockk で ViewModel の単体テスト
  4. 04デバッグ版とリリース版で別のキーを設定
  5. 05GitHub Actions の単体テストを設定

活用シーン

  1. 01購入成功・失敗・キャンセル時の画面を検証
  2. 02Paywall ViewModel の課金処理を分離してテスト
  3. 03プッシュごとに単体テストを実行
  4. 04Google Play Sandbox で更新と決済の一連の流れを確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/revenuecat/ai-toolkit --skill rc-testing

インストール後、Claude Code で/rc-testingを入力して読み込まれたか確認します。

詳細

Android で RevenueCat をテストする

このスキルを使って、RevenueCat Android 統合の高速なテストループを構築します。ほとんどの作業では Test Store が Google Play Sandbox の代わりとなり、BillingService インターフェースによって Purchases をモック可能にし、小規模な GitHub Actions ジョブでプッシュのたびにユニットテストを実行します。

ソース全文:revenuecat.com の章全文を参照してください。


フェーズ 1:調査

変更を加える前に、すでに何があるかを確認します。各項目について、該当するファイル、または「なし」と回答してください。

確認項目確認場所確認したい内容
テスト API キーは設定されていますか?app/build.gradle.kts、local.properties、環境変数デバッグ時に BuildConfig.RC_API_KEY に割り当てられた test_... の値
リリースキーは分けられていますか?build.gradle.kts のリリースブロックgoog_... キーであり、test_... ではないこと
Purchases はラップされていますか?app/src/main/java/**/*Billing*.ktPurchases.sharedInstance を隠すインターフェース
CI はありますか?.github/workflows/*.yml./gradlew testDebugUnitTest を実行するジョブ
シークレットは接続されていますか?GitHub リポジトリの設定、ワークフローの env:secrets から参照される RC_TEST_STORE_KEY
テストライブラリはありますか?app/build.gradle.kts の依存関係io.mockk:mockk と kotlinx-coroutines-test

これらが何もない場合は、フェーズ 3 で最初から構築します。一部がある場合は、不足しているものだけを補います。


フェーズ 2:計画

シナリオごとにテスト方法を選びます。デフォルトは Test Store です。Test Store では再現できないストアの動作が必要な場合に限り、Google Play Sandbox に切り替えます。

シナリオ使用するもの
成功、失敗、キャンセルの各パスTest Store
ViewModel のユニットテストBillingService に対する mockk
プッシュのたびに実行する CITest Store + ユニットテスト
サブスクリプションの更新サイクルGoogle Play Sandbox
保留中の購入(保護者の承認)Google Play Sandbox
エンドツーエンドの決済全体Google Play Sandbox

コーディングを始める前に、計画を短いチェックリストとして tasks/todo.md に記述します。アプリでサブスクリプションを提供する場合は、Test Store で日々の反復をまかなえる場合でも、リリース前チェックリストに Sandbox での確認を 1 回含めてください。


フェーズ 3:実行

ステップ 1:テスト API キーを生成する

RevenueCat ダッシュボードでアプリを開き、アプリとプロバイダーに移動して、Test Store を作成を選択します。test_... キーをコピーします。コミットしないでください。local.properties または CI シークレットに保存します。

ステップ 2:デバッグビルドでキーを設定する
// build.gradle.kts
android {
    buildTypes {
        debug {
            buildConfigField("String", "RC_API_KEY", "\"test_YOUR_KEY\"")
        }
        release {
            buildConfigField("String", "RC_API_KEY", "\"goog_YOUR_KEY\"")
        }
    }
}

CI では、キーが git に入らないよう、環境変数から読み取ります。

// build.gradle.kts
val testKey = System.getenv("RC_TEST_STORE_KEY") ?: "test_placeholder"
buildConfigField("String", "RC_API_KEY", "\"$testKey\"")
ステップ 3:ビルド設定のキーで Purchases を構成する
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) Purchases.logLevel = LogLevel.DEBUG
        Purchases.configure(
            PurchasesConfiguration.Builder(this, BuildConfig.RC_API_KEY).build()
        )
    }
}
ステップ 4:Test Store のダイアログを表示する

デバッグモードでアプリを実行し、ペイウォールから awaitPurchase() を呼び出します。「成功」「失敗」「キャンセル」のオプションが表示されたダイアログが現れます。各選択肢は本番と同じように処理されます。「成功」では有効なエンタイトルメントを含む PurchaseResult が返され、「失敗」では支払いエラーを伴う PurchasesTransactionException がスローされ、「キャンセル」では userCancelled = true を伴う例外がスローされます。エラー処理のすべての分岐を確認して、UI の状態を検証してください。

ステップ 5:Purchases を BillingService でラップする

Purchases シングルトンはモックできません。薄いインターフェースを使うと、テストでフェイクを注入でき、ViewModel を SDK の型から切り離せます。

interface BillingService {
    suspend fun getOfferings(): Offerings
    suspend fun purchase(activity: Activity, pkg: Package): CustomerInfo
    suspend fun getCustomerInfo(): CustomerInfo
}
class RevenueCatBillingService : BillingService {
    override suspend fun getOfferings() =
        Purchases.sharedInstance.awaitOfferings()

    override suspend fun purchase(activity: Activity, pkg: Package): CustomerInfo =
        Purchases.sharedInstance.awaitPurchase(
            PurchaseParams.Builder(activity, pkg).build()
        ).customerInfo

    override suspend fun getCustomerInfo() =
        Purchases.sharedInstance.awaitCustomerInfo()
}
ステップ 6:mockk のユニットテストを書く
class PaywallViewModelTest {
    private val billing = mockk<BillingService>()
    private val viewModel = PaywallViewModel(billing)

    @Test
    fun `purchase success grants access`() = runTest {
        val info = mockk<CustomerInfo> {
            every { entitlements["pro_access"]?.isActive } returns true
        }
        coEvery { billing.purchase(any(), any()) } returns info
        viewModel.purchase(mockActivity, mockPackage)
        assertTrue(viewModel.state.value is PaywallState.Success)
    }
}

各分岐につきテストを 1 つ追加します。成功ではアクセスを許可し、失敗ではエラーを表示し、キャンセルではアイドル状態を維持します。

ステップ 7:最小限の GitHub Actions ジョブを追加する
# .github/workflows/test.yml
name: test
on: [push, pull_request]
jobs:
  unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17
      - name: Run tests
        env:
          RC_TEST_STORE_KEY: ${{ secrets.RC_TEST_STORE_KEY }}
        run: ./gradlew testDebugUnitTest

test_... キーを RC_TEST_STORE_KEY リポジトリシークレットとして保存します。このジョブは、デバイスや Google アカウントがなくても実行できます。


検証

購入ごとに RevenueCat ダッシュボードを開き、顧客に移動してユーザーを選び、購入、エンタイトルメント、CustomerInfo JSON を確認します。イベントタブには、テスト購入で発生した Webhook が表示されます。

出荷前チェックリスト

  • Purchases.logLevel = LogLevel.DEBUG が BuildConfig.DEBUG によって制御されている
  • リリースビルドでは test_ キーではなく、goog_ キーを使用している
  • test_ キーをコミットしていない(環境変数または local.properties を使用)
  • Test Store ダイアログを使って、成功、失敗、キャンセルの各フローをテスト済み
  • Google Play Sandbox で少なくとも 1 つのエンドツーエンドフローを検証済み
  • Webhook エンドポイントがサンドボックスでの購入イベントを受信する

参考資料

コメント