
关于A / B测试的大多数文章都致力于Web开发,尽管该工具与其他平台相关,但移动开发仍然不公平。 我们将通过描述主要步骤并揭示在移动平台上进行A / B测试的功能和行为,来消除这种不公正现象。
A / B测试概念
需要使用A / B测试来测试旨在改善关键应用程序指标的假设。 在最简单的情况下,用户分为两组(对照组)(A)和实验组(B)。 实现该假设的功能仅向实验组推出。 此外,基于对每个组的指标指标的比较分析,得出了该功能的相关性的结论。
实作
1.将用户分组
首先,我们需要了解如何将用户按正确的百分比进行分组,并具有动态更改用户的能力。 如果突然发现一项新功能将转化率提高了146%,并且仅推出了5%的用户,则这种机会将特别有用! 当然,我们将希望立即将其推广给所有用户-而不更新商店中的应用程序和相关的时间成本。
当然,您可以在服务器上组织故障,每当您需要更改某些内容时,请拉后端开发人员。 但是在现实生活中,支持通常是在客户方面或由第三方公司开发的,并且服务器开发人员有足够的事情要做,因此并非总是可以与第三方合作快速调整故障,或者几乎永远不会,因此这种选择不适合我们。 然后,Firebase Remote Config可以解救!
在Firebase控制台的“增长”组中,有一个“远程配置”选项卡,您可以在其中创建自己的配置,Firebase会将其交付给您的应用程序用户。
config是一个映射<parameter key,parameter value>,可以根据条件分配参数值。 例如,对于具有特定版本应用程序的用户,该值为X,对于其他所有用户,该值为Y。有关配置的更多信息,请参见文档的相应部分 。

同样在“增长”组中,有一个选项卡“ A / B测试”。 在这里,我们可以对所有上述包子进行测试。 来自远程配置的键用作参数。 从理论上讲,您可以直接在A / B测试中创建新参数,但这只会增加不必要的混乱,因此您不应该这样做,将相应的参数添加到配置中比较容易。 传统上,其中的值是默认值,并且与对照组相对应,除默认值外,参数的实验值是实验性的。

注意事项 对照组通常称为A组,实验组称为B。如屏幕截图所示,在Firebase中,默认实验组称为“变体A”,这引起了一些混淆。 但是没有什么可以改变其名称的。
接下来,运行A / B测试,Firebase将用户分为与参数的不同值相对应的组,在客户端上收到配置后,我们从中提取必要的参数,并根据该值应用新功能。 传统上,该参数的名称与功能名称对应,并且有2个值:True-应用了功能,False-不应用。 在文档的相应部分中阅读有关A / B测试设置的更多信息。
2.代码
我们不会直接讨论与Firebase Remote Config的集成-
此处将对其进行详细描述。
让我们弄清楚如何组织用于A / B测试的代码。 如果我们只是更改按钮的颜色,那么谈论组织是没有意义的,因为组织没有什么特别的地方。 我们将考虑一种变体,其中根据远程配置中的参数,显示当前(用于对照组)或新(用于实验)屏幕。
您需要了解,在A / B测试到期之后,将需要删除其中一个屏幕选项,在这方面,代码的组织方式必须尽量减少当前实现中的更改。 与新屏幕关联的所有文件都应使用前缀AB调用,并放在具有相同前缀的文件夹中。
如果我们在Presentation层中谈论MVP,它将看起来像这样:

最灵活和透明的类层次结构似乎是:

BaseOrderStatusFragment将包含当前实现的所有功能,但由于架构限制而无法放置在抽象类中的方法除外。 它们将位于OrderStatusFragment中。
AbOrderStatusFragment将覆盖实现不同的方法,并包含必要的其他方法。 因此,在当前的实现中,只有将一类分解为两类的情况才会发生变化,并且基类中的某些方法将变为受保护的开放而不是私有的。
注意:如果体系结构和特定情况允许,您可以不创建基类而直接从OrderStatusFragment继承AbOrderStatusFragment。
在这样的组织中,最有可能偏离所采用的CodeStyle,在这种情况下是允许的,因为在完成A / B测试后,相应的代码将被删除或重构(但是,当然,在违反CodeStyle的地方,您应该发表评论)。
如果事实如此,这样的组织将使我们能够迅速而轻松地删除一项新功能,因为与该功能相关的所有文件都易于通过前缀查找,并且其实现不会影响当前功能。 如果该功能改进了关键指标并决定放弃该指标,那么我们仍然必须努力削减当前的功能,这将影响新功能的代码。
要获取配置,值得创建一个单独的存储库并在应用程序级别注入它,以便可以在任何地方访问它,因为我们不知道应用程序的哪些部分会影响以后的A / B测试。 出于相同的原因,值得尽快提出要求,例如,以及应用程序正常工作所需的基本信息(通常这样的请求是在启动期间发生的,尽管这是一个整体主题,但重要的是它们必须存在于某处)。
好吧,当然,重要的是不要忘记将配置中的参数值放入分析事件参数中,以便您可以比较指标
结果分析
例如,有许多文章详细介绍了如何分析A / B测试的结果。 为了不重复自己,我们只说明本质。 您需要了解,对照组和实验组中指标的差异是随机变量,并且我们不能仅基于实验组中的指标更好而得出结论该功能是相关的。 必须为上述随机变量建立一个置信区间(可靠性水平的选择应委托分析人员选择)并进行实验,直到该区间完全在正或负半平面内-然后才能得出统计上有效的结论。
陷阱
1.获取远程配置时出错对新用户进行比较分析,因为具有相同用户体验的用户以及只有看到过唯一实现选项的用户才应参与实验。 回想一下,接收配置是网络请求,并且可能会失败,在这种情况下,将应用默认值,该默认值通常等于控制组的值。
考虑以下情况:我们有一个将Firebase分配给实验组的用户。 用户首次启动该应用程序,并且“远程配置”请求返回错误-用户看到旧屏幕。 在下一次启动时,将正确处理“远程配置”请求,并且用户会看到一个新屏幕。 重要的是要了解此类用户与实验无关,因此您需要弄清楚如何在分析系统方面过滤掉此类用户,或证明此类用户的数量可以忽略不计。
实际上,此类错误的确很少发生,并且后一种选择很可能适合您,但是从本质上讲,这是一个类似但更紧急的问题-获取配置的时间。 如上所述,最好将Remote Config请求粘贴在会话开始时,但是如果该请求花费的时间太长,则用户将不耐烦等待并且退出应用程序。 因此,您需要解决一个不平凡的任务-选择一个超时来重置Remote Config请求。 如果太小,则可能有很大一部分用户与测试无关。如果太大,则冒着激怒用户的风险。 我们已经收集了有关接收配置时间的统计信息:

注意事项 最近
30天的数据。 请求总数
673529 。 除了网络请求外,第一列还包含来自缓存的配置的接收,因此将其从常规分发形式中剔除。
图形数据:毫秒
| 请求数
|
200
| 227485
|
400
| 51038
|
600
| 59249
|
800
| 84516
|
1000
| 63891
|
1200
| 39115
|
1400
| 24889
|
1600
| 16763
|
1800
| 12410
|
2000
| 9502
|
2200
| 7636
|
2400
| 6357
|
2600
| 5409
|
2800
| 4545
|
3000
| 3963
|
3200
| 2699
|
3400
| 3184
|
3600
| 2755
|
3800
| 2431
|
4000
| 2176
|
4200
| 1950年
|
4400
| 1804
|
4600
| 1607
|
4800
| 1470
|
5000
| 1310
|
> 5000
| 35375
|
2.滚花更新远程配置您必须了解Firebase会缓存“远程配置”请求。 默认的缓存生存期是12小时。 时间可以调整,但是Firebase限制了请求的频率,如果超出了限制,Firebase将禁止我们执行,并会在配置请求中返回错误。可能只适用于数量有限的设备)。
因此,例如,如果我们要完成A / B测试并以100%的比例推出新功能,则需要了解过渡只会在12小时内发生,但这不是主要问题。 考虑以下情况:我们进行了A / B测试,完成了测试并准备了新版本,其中还有另一个具有相应配置的A / B测试。 我们已经发布了该应用程序的新版本,但是我们的用户已经从以前的A / B测试中缓存了配置,并且如果缓存尚未过期,则配置请求不会提取新参数,我们将再次将用户分配给实验组,它将在第一个请求时接收配置的默认值,并在以后破坏新实验的数据。
这个问题的解决方案非常简单-您需要通过重置缓存生存期来在更新应用程序版本时强制执行config请求:
val cacheExpiration = if (isAppNewVersion) 0L else TWELVE_HOURS_IN_SECONDS FirebaseRemoteConfig.getInstance().fetch(cacheExpiration)
由于更新的发布频率不高,因此我们不会超出限制
在此处阅读有关这些问题的更多信息。
结论
Firebase提供了应该使用的非常便捷,简单的A / B测试工具,尤其要注意上述瓶颈。 在进行与A / B测试周期相关的更改时,建议的代码组织将最大程度地减少错误数量。
祝大家好运,A / B测试成功,转换率提高100.5%。