A/B 测试
也叫桶测试或分流测试,指的是针对一个变量的两个版本A和B,来测试用户的不同反应,从而判断出哪个版本更有效,类似统计学领域使用的双样本假设测试。A/B测试是以数据驱动的可回退的灰度方案,客观,安全,风险小,是一种成熟的试错机制。
全景设计
- 策略服务,为策略定制者提供策略
- A/B测试SDK,集成在客户端内,用来处理上层业务去走不同的策略
- 日志系统,负责反馈策略结果供分析人员分析不同策略执行的结果
A/B测试SDK
生效机制
分为冷启动生效和热启动生效。热启动落实策略要及时些,但考虑到一个策略可能关联到多个页面或者多个功能,冷启动可以保持策略整体一致性。
如果一个策略只在一个地方生效的话,可以使用热启动生效机制,而如果一个策略在多个地方生效的话,最好使用冷启动生效机制。
SkeyLab
业务方调用接口的设计
SkeyLab使用的是NSUserDefault保存策略,使得每个用户在使用过程中,不管是在哪个测试桶里,都能够保持相同的策略。
1 2 3 4 5 6
| [SkyLab abTestWithName:@"Title" A:^{ self.titleLabel.text = NSLocalizedString(@"Hello, World!", nil); } B:^{ self.titleLabel.text = NSLocalizedString(@"Greetings, Planet!", nil); }];
|
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| + (void)abTestWithName:(NSString *)name A:(void (^)())A B:(void (^)())B { [self splitTestWithName:name conditions:[NSArray arrayWithObjects:@"A", @"B", nil] block:^(NSString *choice) { if ([choice isEqualToString:@"A"] && A) { A(); } else if ([choice isEqualToString:@"B"] && B) { B(); } }]; }
|
利用范型使conditions支持数组和字典,使其不仅能够支持A/B测试,还能够支持更为复杂的Multivariate testing或Multinomial testing。两者区别在于支持更多版本变体进行测试验证。
人群测试桶划分
SkeyLab使用的是随机分配方式,会将分配结果通过NSUserDefaults进行持续化存储,以确保测试桶的一致性。其实测试桶分配最好由服务端来控制,服务端能够随时根据用户群的维度分布分配测试桶。
测试桶分配代码,array参数就是包含A和B两个版本的数组
1 2 3 4 5 6 7
| static id SLRandomValueFromArray(NSArray *array) { if ([array count] == 0) { return nil; } return [array objectAtIndex:(NSUInteger)arc4random_uniform([array count])]; }
|
保存结果
1 2 3 4 5 6 7 8
| condition = SLRandomValueFromArray(mutableCandidates);
BOOL needsSynchronization = ![condition isEqual:[[NSUserDefaults standardUserDefaults] objectForKey:SLUserDefaultsKeyForTestName(name)]];
[[NSUserDefaults standardUserDefaults] setObject:condition forKey:SLUserDefaultsKeyForTestName(name)]; if (needsSynchronization) { [[NSUserDefaults standardUserDefaults] synchronize]; }
|