mcpField
R
rc-testing

rc-testing

github.com/revenuecat测试与质量76648 次安装1 天前更新
代码仓库

关于 rc-testing

rc-testing 是帮助 Android 开发者建立 RevenueCat 测试流程的技能,使用 Test Store 覆盖购买结果,并通过 BillingService、mockk 和 GitHub Actions 支持单元测试与 CI。

主要功能

  1. 01使用 Test Store 测试购买结果
  2. 02以 BillingService 封装 Purchases
  3. 03用 mockk 编写 ViewModel 单元测试
  4. 04为调试版和发布版配置不同密钥
  5. 05设置 GitHub Actions 单元测试任务

适用场景

  1. 01验证购买成功、失败和取消界面
  2. 02隔离测试 Paywall ViewModel 的计费逻辑
  3. 03在每次推送时运行单元测试
  4. 04用 Google 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 沙盒;BillingService 接口可让 Purchases 支持模拟;一个精简的 GitHub Actions 任务会在每次推送时运行单元测试。

完整源码:请参阅 revenuecat.com 上的完整章节。


阶段 1:调研

在进行任何更改之前,先了解现有内容。针对每个问题,给出对应文件或回答“无”。

检查项查看位置目标
是否配置了测试 API 密钥?app/build.gradle.kts、local.properties、环境变量在 debug 中将 test_... 值绑定到 BuildConfig.RC_API_KEY
Release 密钥是否单独配置?build.gradle.kts 的 release 块使用 goog_... 密钥,绝不能使用 test_...
是否封装了 Purchases?app/src/main/java/**/*Billing*.kt一个可隐藏 Purchases.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 沙盒。

场景使用方式
成功、失败、取消路径Test Store
ViewModel 单元测试使用 mockk 模拟 BillingService
每次推送时运行 CITest Store + 单元测试
订阅续订周期Google Play 沙盒
待处理购买(需要家长批准)Google Play 沙盒
完整端到端支付Google Play 沙盒

编码前,先在 tasks/todo.md 中用简短清单写下计划。如果应用提供订阅,即使 Test Store 能覆盖日常迭代,也应在发布前清单中保留一次沙盒测试。


阶段 3:执行

步骤 1:生成测试 API 密钥

在 RevenueCat 控制面板中打开应用,进入 Apps & providers,然后选择 Create Test Store。复制 test_... 密钥。不要将其提交到代码库。将其放入 local.properties 或 CI 密钥中。

步骤 2:将密钥接入 debug 构建
// 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 对话框

在 debug 模式下运行应用,并从付费墙调用 awaitPurchase()。此时会出现一个对话框,其中提供 Success、Fail 和 Cancel 选项。每个选项的处理方式都与生产环境相同:Success 会返回带有有效权益的 PurchaseResult;Fail 会抛出带有支付错误的 PurchasesTransactionException;Cancel 会抛出异常,并设置 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)
    }
}

为每个分支添加一个测试:成功时授予访问权限,失败时显示错误,取消时保持空闲状态。

步骤 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 控制面板,进入 Customers,选择用户,并确认购买记录、权益和 CustomerInfo JSON。Events 标签页会显示测试购买触发的 Webhook。

发布前检查清单

  • Purchases.logLevel = LogLevel.DEBUG 受 BuildConfig.DEBUG 控制
  • 发布构建使用 goog_ 密钥,而不是 test_ 密钥
  • 未提交 test_ 密钥(环境变量或 local.properties)
  • 已通过 Test Store 对话框测试成功、失败和取消流程
  • 已在 Google Play Sandbox 中验证至少一个端到端流程
  • Webhook 端点会接收沙盒购买事件

参考资料

评论

支持 Markdown