首页 存档 技术 查看内容

iOS A/B Test 方案探索 引子 1 A/B Test 2 开发工程师需要关注的事情 3 iOS A/B Test ...

2018-3-30 13:00 |来自: 互联网 338 0

摘要: 引子 公元2016年末,2017年初,某做旅行产品的互联网公司内,产品经理疯狂的提 A/BTest 需求,以至于该司程序猿谈AB色变,**的产品经理令程序猿们闻风丧胆,苦不堪言...咳咳,扯远了。 近期团队做了很多 AB Test ...

引子

公元2016年末,2017年初,某做旅行产品的互联网公司内,产品经理疯狂的提 A/BTest 需求,以至于该司程序猿谈AB色变,邪恶的产品经理令程序猿们闻风丧胆,苦不堪言...咳咳,扯远了。

近期团队做了很多 AB Test 的业务需求,在这种需求日益见多的情况下,我们不得不提升我们的代码组织方式,以适应或更好的在此类需求上维护我们的代码。所以有了本文,本文主要阐述了业务团队在做 AB Test 的一些想法和思路,才疏学浅,不灵赐教。

1 A/B Test

1.1 A/B Test 是什么?


既然产品经理在 A/B Test 胯下疯狂的输出,那我们就要弄清楚,什么是 A/BTest?为何产品经理如此痴情于 A/B Test ?

A/B Test 就是为了同一个目标制定两个方案(比如两个website,app的页面),让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用情况,哪个方案更接近测试想要的结果,并确信该结论在推广到全部流量可信。

请注意上述那段话中的黑体字,这将是 AB Test 的核心价值所在。

其实 A/B Test 就是我们中学上化学实验课时常做的对照试验,把这种对照试验搬到了互联网上,通过改变单一变量的实验组和原来的对照组做对比,通过数据指标对比,看哪种方案能够提高用户体验(转化率);

1.2 AB Test 的优点有哪些(对产品而言)?


1.2.1 优点1. 灰度发布


灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式。A/B Test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

1.2.2 优点2. 可逆方案


可逆方案,有点类似于之前的灰度发布,只不过不灰度的控制力更强,当我们发布后发现实验组方案出现了严重的故障,或者对比数据量相差悬殊,那么就完全可以全量切换回原来的对照组,保证了线上环境的稳定,不影响用户的正常使用。

这点,对产品而言就是多了试错的可能,想想在之前App动态化匮乏的时代,App的发布就是嫁出去的女儿泼出去的水,一去不复返,发布了的产品用户更新完就不可能在回退到上一个版本。从这一点开始,产品经理就大爱A/B Test !

1.2.3 优点3. 数据驱动


数据驱动,这一点我想至关重要,在目前这种以用户数据为商业土壤的大数据时代,一个产品是以数据驱动,将能够更加铿锵有力的支持这个产品的全线发布,也是产品经理对新方案推进的重要王牌。之前要发布一个新产品,要么美其名曰参考竞品(不反对抄袭,抄袭是赶上竞争对手最快的手段,但是并不是超越的手段),要么脑洞打开,认为某种新的方案或交互体验能带来更多的转化率。这种方法都是没有数据说明的,只能通过项目上线后进行后评估才能确定是否如产品经理所愿真正到达了目标。

通过A/B Test,能在不全量影响线上的正常运转的情况下,通过对照度和试验组的数据对比,在短时间能确定哪种方案的优越,从而让产品的转化率在短时间能得可信性提升。这也正是产品经理说服老板,并彰显其能力价值的精华之处!so,大爱!

2 开发工程师需要关注的事情

2.1 六问产品经理


在做 AB Test 之前,有几个问题是要问产品经理的:

  1. 目标是什么?

  2. AB版本是什么?

  3. 样本量有多大?

  4. 用户如何分流?

  5. 测试时间多长?

  6. 如何衡量效果?

这其实就是我们上面那段话中加粗文字的重点,当然,有些问题是服务端需要关心的,比如问题3和4。

那么客户端开发需要关心哪些个问题呢?

2.1.1 目标是什么?


第一个问题,目标是什么?目的是什么,这是我们需要问的,对客户端而言,A/B Test 就需要客户端维护两套同样业务的代码,这种工作量简单理解就是之前的double,既然会导致工作量翻倍,那就要问清楚,这次做 A/B Test 的目的是什么?评估一下真的值得这样做吗?虽然有时候胳膊拧不过大腿,但或许在你的分析下,某些需求是不需要做 A/B Test 的。例如:竞品已经做了很久方案(你不要告诉我抄都没自信),或者很明显的UI改动是优于之前的方案的,等等。

2.1.2 A/B Test 版本是什么?测试时间多长?


第二个问题,A/B Test 版本是什么?测试时间多长?其实这两个问题,就是在确认这个 A/B Test 方案什么时候上线,什么时候下线。上下线的时间我们要清楚,因为在这段时间内,我们都需要去维护两套代码,而且在 App Size 这么紧张,大家都在搞瘦身的大环境下,你的安装包的过大或需就是用户从一开始就不选择你们产品的理由!A/B Test 方案,代码有写就有删,何时删代码取决于这个 A/B Test 方案何时下线,删完代码后有多久的时间给 QA 测试工程师去测试,这都是要安排的。

2.1.3 如何衡量效果?


对于某些开发每天都要声嘶力竭的说5次以上:“这个(需求)是要算(研发)成本的呀。”这样用力扣研发成本,尽量把价值低收益低的需求砍下去,把收益不明确的需求排到后面去,相当于在输出几乎不变的基础上,节约了2-3个开发工程师。这也是长期维持团队的诀窍,从源头上精简,而不是苛求超人般的程序员。

如何衡量效果,就是来判断这种需求是否是价值低收益低或不明确的项目,我们都想做有价值的东西,而不是随随便便随时准备砍掉的功能,希望产品经理敢想,而且加以思考!

3 iOS A/B Test 方案探索

好了,扯完了产品篇,咱们进入正题。
既然原本一套代码有了两种逻辑,或者两种UI样式,就需要从原本的逻辑中拆出来,其必然结果是多了一个if判断语句,那如果判断的地方多了,咱还这样if、if、if、if、i....就太失水准了,常言道:写业务代码,搬得一手好砖是程序员的基本要求。接下来讲下小生的 A/B Test 方案探索历程。

3.1 方案探索历程


先来大概介绍本次探索的业务背景:

3.1.1 A/B Test 方案背景介绍

  • A 方案 线上方案,全量;

  • B 方案,适用于 A 中的一种情况,是 A 方案的子集;

  • 非标准 A/B Test,只是过渡,因为 A 方案为全量方案,无法被下掉,B方案为部分A中的;

我们就以 iOS 中典型的 UITabelView 中的 Delegate 和 DataSource 的协议函数分 A/B 方案来说;

3.1.2 最基本的函数 A/B







刚刚说了,A 方案是一个全量方案,所以这里的switch会有一个默认方案。但是这种写法实在是太low了,每一个调用函数中都去判断一次A/B,影响效率暂且不提,维护起来也是坑坑坑,看见第二张图的函数列表页觉得头大,而且也导致了Controller过于庞大,如果再有一个C方案岂不是要炸?所以这种方案不可取。

3.1.3 方法选择子 字典,缓存式 A/B






由于Objective-C 的Runtime 动态特性,我们可以把方法选择子缓存在一个字典中,在需要确定 A/B 方案的调用处判断一次,得到对应方案的方法缓存字典,在调用的时候,只需要去对应的缓存字典中调用就可以了,当然这里需要扩展NSObject类中的- (id)performSelector:(SEL)aSelector withObject:(id)object;使其支持多个参数的传递。

- (id)fperformSelector:(SEL)selector withObjects:(NSArray *)objects
{  NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selector];  if(methodSignature == nil)
  {    @throw [NSException exceptionWithName:@"抛异常错误" reason:@"没有这个方法,或者方法名字错误" userInfo:nil];    return nil;
  }  else
  {    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
    [invocation setTarget:self];
    [invocation setSelector:selector];    //签名中方法参数的个数,内部包含了self和_cmd,所以参数从第3个开始
    NSInteger signatureParamCount = methodSignature.numberOfArguments - 2;    NSInteger requireParamCount = objects.count;    NSInteger resultParamCount = MIN(signatureParamCount, requireParamCount);    for (NSInteger i = 0; i
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部